20210507のCSSに関する記事は12件です。

切り抜く要素のサイズに合わせてSVGでclip-pathする

発生した問題 何も考えずSVGで要素をclip-pathすると、切り抜きたい要素のサイズに合わせて切り抜いてくれませんでした。 こうなって欲しいのに... こうなる... 問題発生時のコード この問題が発生しているとき、みなさんのソースコードも以下と似た状態だと思います。 JSXなので少し記述がHTMLと異なりますが、読み替えていただけると幸いです。 // 切り取りたいSVGの形 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103.758 103.758" height={0} width={0} > <clipPath id="super-ellipse"> <path d="M64.36,13c35.815,0,52.4,15.545,52.4,51.36s-16.583,52.4-52.4,52.4S13,100.175,13,64.36,28.545,13,64.36,13Z" transform="translate(-13 -13)" fill="none" /> </clipPath> </svg> // 切り取る対象の要素 <img src={profileImageSrc} style={{ clipPath: 'url(#super-ellipse)' }} /> 解決方法 clipPathにclipPathUnits="objectBoundingBox"をつける pathのサイズを0-1に正規化する 1.はそのままなのですが、2.のpathのサイズを正規化するというのが重要です。clipPathUnits="objectBoundingBox"をつけると、pathがviewBoxの範囲ではなく、0-1の範囲で描画されるようになります。 pathの項目一つ一つの数値をviewBoxの数値で割ることでも可能ではありますが、手っ取り早くtransformでscaleを指定しましょう。 scaleで指定する数値は、以下の計算で求めることができます。 1 / viewBoxの数値 transformでtranslate等が指定されていれば、その数値もviewBoxの数値で割る必要があります。 上記のコードの場合は、scaleに指定する数値は、 scale = 1 \div 103.758 = 0.009637 transformの数値は、 transform = -13 \div 103.758 = -0.125281 です。 解決後のコード <svg> <clipPath id="super-ellipse" clipPathUnits="objectBoundingBox"> <path d="M64.36, 13c35.815, 0, 52.4, 15.545, 52.4, 51.36s-16.583, 52.4-52.4, 52.4S13, 100.175, 13, 64.36, 28.545, 13, 64.36, 13Z" transform="translate(-0.125281 -0.125281) scale(0.009637)" /> </clipPath> </svg> // 切り取る対象の要素は同じ 切り抜けました! ちなみに今回切り抜いたSVGの形は、スーパー楕円という図形です。 丸よりも丸みを感じる!? スーパー楕円の魅力とデザイン
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pinterest風なGridレイアウトをforeachの順序を崩さずに実現するまで【JS|意外とかんたん】

今回実現すること フロントエンドをされている方なら1度は憧れる(?) Pinterest風なGridレイアウトを ライブラリを使わず、かんたんなJSで実現したので 過程と解説を書いていきたいと思います。 既に個人開発でつくったWebアプリには実装していて 問題なく動いてます。 実際に実装した画面がこちらです。 チャットライクな寄書きWebサービス Cheers Box もし実装する機会があれば、参考にしていただけれ幸いです。 まずは調査しました 今回、Pinterest風なGridレイアウトを作る上で、 foreachの順序を崩さずに、画面上から下へcreated_atの降順になるようにする という仕様がありました。 順序を表すとこう言う感じです。 ① ② ③ ④ ⑤ ⑥ まず見つけた記事 【WordPress】cssの追記のみでPinterest風のグリッドデザイン 順序はこのようになってしまいます。 ① ④ ② ⑤ ③ ⑥ 次に見つけた記事 Masonryレイアウトをたった3行のシンプルなCSS Gridで簡単に実装できるようになります めちゃくちゃ簡単そうですが まだブラウザ互換的に使い物になりません。 ライブラリも発見 Pinterest風なGridレイアウトを簡単に作れるライブラリもあるようです。 driveway|http://jh3y.github.io/driveway/ Masonry|https://masonry.desandro.com/index.html しかし 「たかだか1画面のレイアウトのためにライブラリいれるのもなあ…」 ということで自作することにしました Pinterest風なGridレイアウトの原理 自作する前に、Pinterestが実際どのように実現しているかを調べてみました。 ソースコードを見るとおそらく どうにかしてJSで各要素にstyleを書き込んでいるということが予想できます。 そこで、それを真似することにしました。 やることは、 要素のサイズや要素同士の余白計算して、 計算結果を次の要素のstyle transformに設定する ということだけです。 いたってシンプルですね。 コードと解説 簡易的にhtmlをこういうものだとします。(実際のWebアプリにはhtml使ってませんが) index.html <div class="card-wrapper"> <!-- Gridレイアウトしたい親要素 --> <div class="card"> <!-- Gridレイアウトしたい要素 --> <img src="img01.png"> </div> <div class="cardr"> <img src="img02.png"> </div> <div class="card"> <img src="img03.png"> </div> <div class="card"> <img src="img04.png"> </div> <div class="card-"> <img src="img05.png"> </div> <div class="card"> <img src="img06.png"> </div> </div> 今回Pinterest風なGridレイアウトで表示したい要素には 画像が含まれています。 そこでまずは、画像が全て読み込まれたかどうかを判定します。 index.js const images = document.querySelectorAll('img'); let loadCnt = 0; if (images.length > 0) { for (const img of images) { let image = new Image(); image.src = img.src; image.addEventListener('load', () => { loadCnt++; if (loadCnt == images.length) { // 画像が全部読み込まれたか判定しています makePageCardGridLayout(); // この後、このメソッドの中身を書きます } }) } } ここまでで、ページないの画像全て読み込んだら、makePageCardGridLayout() というメソッドが呼ばれるところまできました。 次にmakePageCardGridLayout() でPinterest風なGridレイアウトを実現していきます。 index.js makePageCardGridLayout() { const cards = document.getElementsByClassName('card'); if(cards.length > 0) { let evenPosX = 0; let evenPosY = 0; let oddPosY = 0; let gridWindow; let sh; for (let i = 0; i < cards.length; i++) { const oddPosX = cards[0].clientWidth; i == 0 ? gridWindow = cards[0].closest('.card-wrapper') : i; // Gridの親要素を取得します if (i % 2 == 0) { // Gridに配置される偶数番目の要素に対する処理 cards[i].setAttribute("style", "transform: translateX("+ evenPosX +"px) translateY(" + evenPosY + "px)");  // スタイルに配置したい位置を記述します evenPosY = evenPosY + cards[i].clientHeight;  // 今のY軸の位置に要素の高さを加算 } else if (i % 2 != 0) {  // Gridに配置される奇数番目の要素に対する処理 cards[i].setAttribute("style", "transform: translateX(" + oddPosX + "px) translateY(" + oddPosY + "px)");  // スタイルに配置したい位置を記述します oddPosY = oddPosY + cards[i].clientHeight;  // 今のY軸の位置に要素の高さを加算 } } evenPosY > oddPosY ? sh = evenPosY + 150 : sh = oddPosY + 150; // 全部の要素が配置し終わったら、親要素の高さを設定するために計算します gridWindow.style.height = sh+'px'; // 計算した高さを親要素に指定します } } このように配置したい要素(.card)を取得して、forで1つずつ配置する場所を指定してあげています。 (なんでforなのかは覚えていません。笑 for ofでもいけるはずです) ① ② ③ ④ ⑤ ⑥ 奇数番目の要素は、1つ前の奇数番目の要素の位置とサイズから配置位置を計算 偶数番目の要素も、1つ前の偶数番目の要素の位置とサイズから配置位置を計算しています。 transform: translateで子要素の位置を指定しているので、 親要素の.card-wrapper は高さが0の状態になっています。 そこで最後に、奇数番目か偶数番目で下側にある要素から、150px加算して親要素の高さに指定しています。 コードは以上です。 レスポンシブを実現するのも、 画面サイズによって、makePageCardGridLayout()を流用したメソッドを呼び出せば スムーズに実現できると思います。 結果、意外とかんたんにできた 「え、もうおわり?」 「思ったよりコード量少ないな」 と思われた方も多いんじゃないでしょうか。 実はこちらのWebアプリには、ライブラリを使用せずに JSで実装した挙動が他にもいくつかあります。 チャットライクな寄書きWebサービス Cheers Box たとえば、 寄書き作成時に、生のJSなのにSPAのようなプレビュー機能がある 寄書きは、メッセージがチャットのように1つずつ時間差で表示される 下記の画像下部の部分はメニューで、画面全体がメニュー連動のカルーセルになっている などです。 それらもなるべくシンプルに実装してみたので また実装方法を記事にできたらと思います。 より良い実装、おすすめのライブラリがあれば、ぜひご教授ください。 最後までご覧いただいてありがとうございました?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

border-radius で、上だけ(下だけ)を角丸にする

わかりやすかった記事をメモ↓
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WordPressちゃんとやろうと思ってVScodeにphpcs入れたらめっちゃ怒られた

この記事は 久しぶりにWordPressに触れる機会があったのでちゃんとしようと思ってVScodeにphpcsていうプラグイン入れたら早速めっちゃ怒られたので一個ずつ解決していくぅ ちなみに普段ほとんどWordPress触らないからマジで初心者向けです。 phpcsはこれ https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs エラー内容と解決方法 共通 1. 改行前スペース Whitespace found at end of line 改行前に半角スペースが入っていたりするとこう怒られる。 半角スペースを消すと怒られなくなる。 2. コード後の改行 File must end with a newline character コードのあとに改行がないときの怒られ方。改行を足すと機嫌は直る。 3. コメントの下の空改行 There must be no blank lines after the function comment コメントの下に空の改行があるとこれが出る。空改行を消すとエラーが消える。 4. ドットの左右は半角スペースを Contact operator must be surrounded by a single space ドットの左右に半角スペースを入れないとこうなる。入れると直る。 5. コメント文の最後には.か!か?をつける Inline comments must end in full-stops, exclamation marks, or question marks 文章の最後に.か!か?がついてない時の怒り方。日本語と一緒で文章は句読点で終わらせよう 6. コメントが見つからない Missing file doc comment WordPressのファイルは、それぞれがなんのファイルなのかをコメントで記す必要があるらしい。 それがないって怒っているのが上記のエラーメッセージ。 /** * Header * @package ThemeName */ こんな感じで、概要と@package ほにゃららを入れてあげると直る。 @package以下はなんでもよいらしい。テーマの名前。 このサイトわかりやすかった WordPress コーディングスタンダードの正式な書き方をまとめてみる – ミルログ functions.php 1. コメントが見つからない その2 Missing file doc comment 一個前のエラーと一緒だけど、関数を作成している場合には関数ごとにもコメントが必要 //functions.phpのDoc /** * Functions * * @package ThemeName */ //関数$my_enqueue_scripts(任意の関数名)のDoc /** * $my_enqueue_scripts. */ 2. バージョン記載 Resource version not set in call to wp_enqueue_style(). this means new versions of the style will not always be loaded due to browser caching. 読み込んだCSSファイルにバージョン記載がない場合の内容。何らかバージョン情報を記載してあげると機嫌が直った。 //怒られる wp_enqueue_style( 'common-css', get_template_directory_uri() . '/assets/css/styles.min.css', ''); //怒られない wp_enqueue_style( 'common-css', get_template_directory_uri() . '/assets/css/styles.min.css', '', '1.0.0' ); header.php 1. スタイルシート等の読み込み方法 Stylesheets must be registered/enqueued via wp_enqueue_style スタイルシートはwp_enqueue_styleで読み込んでねという。 JSもwp_enqueue_scriptsで読み込んでないと同じように怒られる。 2. 読み込みはfunctions.phpに All output should be run through an escaping function (see the Security sections in the WordPress Developer Handbooks), found 'get_template_directory_uri.' JS,jQuery,CSS周りの記述をheadに入れていたら言われた。 これは主にURLをエスケープ処理してない場合に出る文言らしい。 そもそもfunctions.phpに入れてしまえば怒られなくなったから大人しくfunctions.phpにほっぽった。 まとめ とりあえずここまで。まだいっぱい出る気がするのでそのときは追記していくぅ(2021/05/07)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

静的なToDoリスト

概要 HTMLとCSSでToDoリストを作りました。 JSで動きを付ける前の静的なサイトです。 ①タスク入力欄 ②タスクの優先度をラジオボタンで作りました。 ③inputから入力された値がテーブルタグに追加されます。 ④完了したタスクはチェックボックスをクリックすることにより削除されます。 HTML(入力欄) ToDo入力欄です。 index.js <section1> <div class="form"> <label for="todo" class="todos">ToDo</label> <input type="text" placeholder="タスクを入力してね" id="todo"> <input type="radio" name="todo" value="high" class="radio1"> <label>高</label> <input type="radio" name="todo" value="medium" class="radio2"> <label>中</label> <input type="radio" name="todo" value="low" class="radio3"> <label>低</label> <button class="submit">DO</button> </div> </section1> 1,ラジオボタン input要素のtype属性にradioを追加するとラジオボタンになります。ラジオボタンは、複数の選択項目のうち1つだけ選択できる形式のボタンです。共通項目に使用するラジオボタンにはすべて同じ名前を指定する必要があります。 またデータが送信されたときにどの項目が選択されたのかを判別するためにvalue属性には個別の値を指定します。 今回のnameはtodo、valueは優先度の高さheigh,medium,lowとしました。 HTML(テーブル) 次にデータ追加後のデータが反映される、テーブルです。 index.html <section2> <table> <caption>リスト</caption> <tr> <th class="col-1">日付け</th><th class="col-2">ToDo</th><th class="col-3">重要度</th><th class="col-4">完了</th> </tr> <tr> <td>5/5</td><td>ご飯を食べる</td><td>高い</td><td><input type="checkbox" name="do" value="Done"></td> </tr> </table> </section2> 1,trタグ テーブルタグの行に当たります。 2,th table headerの略です。 このリストの見出しに当たります。また,各見出しの幅を設定するためにclass属性を付与しました。 CSSでは以下のように設定しました。 style.css .col-1 { width: 10%x; } .col-2{ width: 60%; } .col-3 { width: 10%; } .col-4{ width: 10%; } 3,td テーブルタグのデータです。 ToDoフォームに入力されたデータが反映されます。 4,チェックボックス input属性にcheckboxを指定するとチェックボックスになります。チェックボックスは、複数の選択項目の中で個数を限定せずに選択できるようにする場合に使用します。 name,value属性はラジオボタン同様です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

~以外の要素をスタイリング

~以外の要素をスタイリング p:not(.クラス名){ スタイリング}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SafariだけにCSS適用するためのmixinを作りました

最近ちょくちょく書くことがあり、どうせならmixin書いたほうが早いやとなったので。 mixin.scss @mixin safari { @at-root _::-webkit-full-page-media, _:future, :root & { @content; } } main.scss .selector { background-color: yellow; @include safari { background-color: pink; } } ↑みたいに書くと、↓にコンパイルされます main.css .selector { background-color: yellow; } _::-webkit-full-page-media, _:future, :root .selector { background-color: pink; }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Bootstrap 5 と smooth-scroll.js の相性が悪かった話

どのような現象になるか Bootstrap5 と smooth-scroll.js (など、おそらく JavaScript を使ってのスムーズスクロール全般に言える可能性がある)を導入すると、スクロールが ”つっかかる” 動きになりました。(Chrome,Edge で確認。その他未確認。) Bootstrap4 ではそのような動きでなかったため、どの部分で相性が悪いのかと探っていたら、Bootstrap5では、しれっと、CSSでスムーズスクロールを実現する、scroll-behavior: smooth; が入っていやがりました。 ひとまず こうやることで回避 Bootstrap 5 の CSS から、以下が省かれていれば良いってことになるはずです。 @media (prefers-reduced-motion: no-preference) { :root { scroll-behavior: smooth; } } せいぜい上記部分なので、ダウンロードしたCSSを直接編集でも大丈夫かと思いますが、カスタマイズのやり方は以下などにて。 結論 素直にCSS scroll-behavior: smooth; を導入しましょう! smooth-scroll.js のgithubを確認すると、「DEPRECATION NOTICE」 つまり 「廃止の通知」となっていて、CSSで導入したほうが良いよ、みたいな事が書いてありました…… ヘッダサイズの調整について CSS scroll-margin-top で調整しましょう。 こんな感じ。 html, body { scroll-padding-top: 60px; } ヘッダのサイズを自動で取得してくれるんで、js の方が楽ちんなんだけどなぁ。 bootstrap5 でヘッダサイズ算出機能やスピード調整などもあると良いですね。(あるかも知れないですね) safari ブラウザについて 知らない子にしちゃおう…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ページトップリンク+スムーススクロール【作成中】

概要 下記3つの方法で実現します jQuery CSS JavaScript jQueryでの実現方法 参考書籍 動くWebデザイン アイディア帳 実現方法 ページトップリンク aタグでトップ(#)にリンクする -----省略----- <p id="page-top"><a href="#">Page Top</a></p> ページトップリンクをクリックするとjQuery animate scrollTop:0 へ移動させる $('#page-top').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); 結果 思った通りに動作しました return falseの意味は下記で確認しました 【JavaScript】return falseの意味について総まとめ。コード付で解説 CSSでの実現方法 参考 CSSのみ!簡単にスムーズスクロールを導入する htmlはjQueryの場合と同じです html { scroll-behavior: smooth; } 結果 思った通りに動作しました 注意点 Safari、Opera、IEには対応していません JavaScriptでの実現方法 参考 【脱jQuery】Javascriptのみでスムーススクロールを実装【コピペ】 htmlの内容はjQueryに加えてid要素を付与 -----省略----- <p id="page-top"><a id = "page_top_link" href="#">Page Top</a></p> JSでaタグのクリックでスムースクロールする ※思っていたより簡単 const smoothScrollTrigger = document.getElementById("page_top_link"); smoothScrollTrigger.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); });
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ページトップリンク+スムーススクロール

概要 下記4つの方法で実現します jQuery CSS JavaScript JavaScript+Vue.js jQueryでの実現方法 参考書籍 動くWebデザイン アイディア帳 実現方法 ページトップリンク aタグでトップ(#)にリンクする -----省略----- <p id="page-top"><a href="#">Page Top</a></p> ページトップリンクをクリックするとjQuery animate scrollTop:0 へ移動させる $('#page-top').click(function () { $('body,html').animate({ scrollTop: 0 }, 500); return false; }); 結果 思った通りに動作しました return falseの意味は下記で確認しました 【JavaScript】return falseの意味について総まとめ。コード付で解説 CSSでの実現方法 参考 CSSのみ!簡単にスムーズスクロールを導入する htmlはjQueryの場合と同じです html { scroll-behavior: smooth; } 結果 思った通りに動作しました 注意点 Safari、Opera、IEには対応していません JavaScriptでの実現方法 参考 【脱jQuery】Javascriptのみでスムーススクロールを実装【コピペ】 htmlの内容はjQueryに加えてid要素を付与 -----省略----- <p id="page-top"><a id = "page_top_link" href="#">Page Top</a></p> JSでaタグのクリックでスムースクロールする ※思っていたより簡単 const smoothScrollTrigger = document.getElementById("page_top_link"); smoothScrollTrigger.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); }); JavaScript+Vue.jsでの実現方法 htmlはクリックイベント追加 <footer id="footer"> <p id="page-top"><a v-on:click = "page_top_click" href="#">Page Top</a></p> -----省略----- </footer> var footer = new Vue({ el:"#footer", methods:{ page_top_click:function(e){ e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth', }); } } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

検索ボックスの中にアイコンを入れる

某サイトのこれを真似してみたくなったので、備忘録として書きます。 <header> <div class="header-inner"> <h1>TESTタイトル</h1> <form> <input type="text" placeholder="アニメタイトルや声優で検索♪"> <button>あ</button> </form> </div> </header> あ はアイコンとします まだ程遠いですね。 1. form周りを整える .header-inner form input { width: 300px; height: 100%; display: block; padding: 0px 20px; border-radius: 20px; border: 1px solid black; font-size: 20px; line-height: 1; } inputタグはインライン要素なので、扱いやすいようにblock要素にします。 border-radiusでフォームを丸くします。 文字の打ちはじめの位置が左端スタートになってしまうので、input内の両端にゆとりを持たせるため padding を指定します。 2. placeholderに対してCSSを当てる .header-inner form input::placeholder { font-size: 14px; position: relative; bottom: 2px; } 3. ボタンを 検索窓の中に持ってくる .header-inner form { display: block; position: relative; height: 40px; } .header-inner form button { position: absolute; right: 7px; top: 50%; font-size: 25px; transform: translateY(-50%); } ここで、 position:relative, position:absolute が出てきます。 position:relative の起点は、現在いる位置からになります。 position:absoluteは、何も指定していなければページ全体になります。しかし、親要素にposition:relativeを加えることで、親要素を起点にすることができます。 なので今回のケースだと、 - formに対して position:relative を指定する - buttonに対して position:absolute を指定して、 formを親要素として、位置を決める ことによって、ボタンの位置をform内で自由に動かすことができます。 top: 50%; transform: translateY(-50%); を指定することによって、親要素の高さが可変になっても button の位置が真ん中をキープするようになります。 だいぶ近くなりました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【備忘録】カスタムデータ属性(data-*)について

初めに cssやjavascriptでカスタムデータ属性が使われている。カスタムデータ属性とは何か、そして使い方について備忘録として残します。 ※内容に間違いなどがある場合はご指摘をよろしくお願いします。 カスタムデータ属性とは htmlのタグに固有の値を付与してcssやjavascriptでその値を取得して利用できるようにしたもの。 書き方 htmlでカスタムデータ属性を付与したいタグにdata-*という形式で指定。divタグだと以下のようになる。 <div data-属性名=値></div> 属性名と値は任意のものであり、自由に指定できる。 例として以下のようにdata-hogeというカスタムデータ属性を指定したとします。 <section class="custom_data_section"> <div class="test" data-hoge="text">Hello World</div> </section> cssで利用する場合 まずhtmlのdivタグにdata-hogeというカスタムデータ属性を付与します。 ①セレクターとして使う [data-属性名]という書き方でセレクターとして使います。 [data-hoge] { color: red; } /* .testを付けても結果は同じ */ .test[data-hoge] { color: red; } ②擬似要素として使う 擬似要素afterやbeforeの中身としてcontentプロパティにattr()関数を使ってカスタムデータ属性の値を渡します。 attr()関数について:https://developer.mozilla.org/ja/docs/Web/CSS/attr() .test::before { content: attr(data-hoge); font-size: 50px; color: purple; } data-hogeの値"text"が画面に表示されました。 javascriptで利用する場合 ①カスタムデータ属性の設定 querySelectorで.testを取得し、「test.dataset.属性名 = 値」で新しいカスタムデータ属性を設定できます。 const test = document.querySelector(".test"); test.dataset.huga = 20; コンソールで確認すると「data-huga」というカスタムダータ属性ができました。また、値として"20"と表示されます。 ②カスタムデータ属性の値を取得 「test.dataset.属性名」で簡単に取得できます。 const test = document.querySelector(".test"); const hoge = test.dataset.hoge; console.log(hoge); ③カスタムデータ属性の値を変更 「test.dataset.属性名 = 変更する値」で値の変更ができます。 const test = document.querySelector(".test"); test.dataset.hoge = "hello"; console.log(test); コンソールで確認するとtextからhelloに変わっていることがわかります。 参考サイト https://www.webprofessional.jp/how-why-use-html5-custom-data-attributes/ https://qiita.com/k152744/items/c96fcf0141798bf48dd7 https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/data-* https://techacademy.jp/magazine/24740 https://whiskers.nukos.kitchen/2016/11/19/data-attr-style.html https://twotone.me/web/2658/ https://apex-traders.net/html-custom-data/ https://developer.mozilla.org/ja/docs/Web/CSS/attr()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む