本セッションの登壇者
セッション動画
それでは始めたいと思います。
自己紹介ですが、久保知己と言います。株式会社まぼろしでCSSを書いています。今回のスライドですが、けっこう作りすぎてしまったので一部は省略していきます。そのかわり、共有する資料にはちゃんと説明が書いてあるので、詳細はそちらをご確認ください。
![](https://res.cloudinary.com/techfeed/image/upload/v1679902137/entries/nbh2qwwjm1u0dvtaxbiw.png)
それでは進めていきたいと思います。”Custom properties”だと名前が長いので、以後「CSS変数」と言っていきます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679902291/entries/frhd3w8atqjn3fmduabm.png)
CSS変数とは
CSS変数というのは、CSSだけで変数の機能を実行できます。CSSにもうそのまま「-- (ハイフンハイフン)」で何か名前を付けて、var関数でその変数を取り出すこともできますし、JavaScriptからのアクセスもできます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679902365/entries/d8svwsiq6cxrbhmob2ah.png)
CSS変数の特性ですが、たとえば:root
というところにCSS変数を定義すると、HTML全体にCSS変数が使用できるようになります。
![](https://res.cloudinary.com/techfeed/image/upload/v1679902439/entries/luwskrzgsodltkqgoog2.png)
またCSS変数というのはHTMLの子孫に継承されていくので、特定の場所に設定するとそれ以降の子孫のHTMLでCSS変数を効かせられます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679902943/entries/co79r6ibyetbrcb9eehh.png)
CSS変数の使い方
次に、CSS変数の使い方ですが、よく使われる方法がトークンとして使われる方法ですね。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903005/entries/tbiyp5gkxjprsfremlor.png)
トークン以外にもJavaScriptと組み合わせて使うこともできます。こちらは左ナビゲーションをマウスで動かしたりというようなナビゲーションですね。こちらも従来の方法だとインラインスタイルにてCSSの宣言が必要だったんですが、CSS変数を使うことによってスマートに書くこともできます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903071/entries/mam6qc436s0kcwbiqkeo.png)
またTailwindとの相性も良く、こういうこともできますね。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903131/entries/apakivfak7oyokntwfxx.png)
細かい説明は資料に記載しているので、ここではちょっと省略します。
Component思考のCSS変数 - CSSの変数化にChatGPTを使う
ここからが本題の「Component思考のCSS変数」です。コンポーネントっていろいろあるのですが、わかりやすいようにボタンから進めていきたいと思います。
ボタン、いろいろあります。一番上の白い点線で囲っているところにベースのボタンを用意しました。その下にバリエーションのボタンを用意しています。まずベースのボタンから作成してみましょう。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903252/entries/ksvhgnhsz6dslzmjovg0.png)
従来どおりのSCSSだとこういう感じですね。何の変哲もないものです。is関数セレクタを使ったりとか、あとはaria-pressed=true
というのを使って、ボタンが押された状態とか、disabledとか、いつもどおりの感じでボタンを作ります。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903353/entries/lktis8edorreq83nyti9.png)
![](https://res.cloudinary.com/techfeed/image/upload/v1679903396/entries/rgx2kqljhkelnkkdcop6.png)
次にバリエーションの部分です。2段目は塗りの状態のボタンで、ホバーもしますし押した状態、そしてdisabled、3段目はアウトライン、ゴーストボタン的なやつですね。今日はこれをラインと呼びます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903502/entries/xdxnlxwpjr5gytjuoevw.png)
こういう感じでバリエーションを作成しました。これも従来どおりの作り方です。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903553/entries/n0zeiwckrftprqpvuwyu.png)
これをCSS変数化してみます。CSS変数化するにあたって、ChatGPTを使うと非常に楽です。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903599/entries/tdi9jj21pbovmazkyf1v.png)
先ほどのベースで作ったボタンに対して、ChatGPTでテンプレート構文が使えるので、「こういう感じでやってよ」というと良い感じにChatGPTが吐き出してくれます。ただ、ちゃんとうまくすべて吐き出してくれるわけじゃないので、ちょっとだけ手直しをしました。たとえば、ChatGPTの場合はCSS変数をすべて:root
に対して吐き出します。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903673/entries/igets0rjoyjtby9q5ohg.png)
僕のほうは:root
の変数をそのままコンポーネントの中に入れてしまいました。こうするとコンポーネントで使っているCSS変数が何なのか、非常にわかりやすくなります。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903712/entries/jvcsxqalnuggz4bvmhis.png)
次にバリエーションのCSSです。先ほどいろいろ書いていたバリエーションのCSSなんですが、塗りの部分に関しては3行で終わるようになってしまいました。非常に短くなっていますね。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903766/entries/a5emv0jul325nmbvkyty.png)
従来のSCSSの記述とCSS変数化した記述の両方を見てみると一目瞭然です。しかもCSS変数はCSSネイティブで、そのまま生の状態で使うことができるので、非常にありがたい機能ですね。これで何が起こっているのかと言うと、セレクタを省略しています。なので行数がかなり短くなったと言えます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679903859/entries/qilk9yl8xrf4o7aeirfe.png)
次にこの「セレクタを縮める」に関連してCSSアニメーションの例も見てみましょう。キーフレーム(@keyframes
)をこのように1つだけ用意してあります。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904031/entries/k6j4jg9yzztpgvuwsfvm.png)
このキーフレームを利用して、ベースのボタンに対してアニメーションを付けたいというクラスを用意したらアニメーションが走るようにしています。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904124/entries/b1v5pr0xmhwdeavm6yx6.png)
そうすると、ベースのボタンに対して設定したものが、バリエーションも含めたすべてにアニメーションが効くようになります。こちらなんですけれども、本来であれば白に対しての黒、緑色背景に対しての黒背景といった具合にキーフレームをそれぞれ用意しなければいけなかったものが、1つのキーフレームでこのようにアニメーションができるようになりました。セレクタが非常にコンパクトになります。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904197/entries/bgtoahwtknyf4pmtkxv4.png)
詳細度の分離
つづいて詳細度の分離について説明していきたいと思います。通常であればプロパティと値は同じ詳細度になるはずです。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904296/entries/odeyajfjxtyesq1drlcl.png)
CSS変数を使うことによってこの状態でもまったく問題ありません。期待どおりの描写が行えます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904357/entries/zf9qeafzg89bebzuuono.png)
また、プロパティと値が反対になったとしても描写してくれます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904401/entries/ycmemhzex9gqiywjzbsh.png)
こちらはあまり良い例ではないんですが、ボタンのコンポーネントに対して「#legacy」というIDを付与しました。この状態でボタンの通常時だけの色を変えたいとき、宣言を設定するとすべての色が変わってしまいます。こちらはIDの詳細度が強すぎるためにこうなってしまった例です。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904446/entries/r8vyx3iqqicb3rijpjbt.png)
同じように「#css-variables」というIDを設定しています。ただ、CSS変数を使うことによって、ちゃんと通常時の色だけを変えることができます。また、押した状態やdisabledの状態ではちゃんと元の色をある程度保持してくれます。最後の行の--button-disabled-border
で上書きしてる部分はあるのですが、ある程度保持してくれます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904534/entries/grgu7zizzknvbd6ucibw.png)
また、架空の話なんですけども、大きな大きな企業のLP案件で、リセットCSSのa
タグに!important
が付与されていたとします。しかもLPページにしか編集権限がないので、このリセットCSSを編集することができません。そうなるとどうなるかというと「!important祭り」が発生します。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904671/entries/hilvf1n7mr32nqoft1nx.png)
![](https://res.cloudinary.com/techfeed/image/upload/v1679904672/entries/pztadhxcxcrdygorbmmo.png)
ただ、これもCSS変数を使えば解決できます。リセットCSSは変更できないので、ここで:where
を使って、.lp-demo
みたいなLPの起点となるようなクラス名を設定してあげて、a
タグに対して!important
で上書きしたいものにCSS宣言を設定してあげます。そうすると以後、このCSS変数を再定義してあげるだけで!important
を使用せずにちゃんとスタイルが反映されます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904756/entries/lvulsqot0fdmjjjnvn0j.png)
まとめ
では、最後のまとめにいきたいと思います。まとめはもうタイトルの通りなんですけれども、セレクタは省略して値にアクセスできる方法があります。もうひとつは、プロパティと値の詳細度は分離ができます。
![](https://res.cloudinary.com/techfeed/image/upload/v1679904825/entries/vlxoennox9bioacczlbt.png)
以上です。ありがとうございました。