CSS Custom Properties(CSS Variables、CSS変数)の基礎からメリット・デメリット、Sass/Stylusなどのプリプロセッサ変数との使い分け、NES.cssを題材に実践的な事例を紹介。
https://twitter.com/bc_rikko
CSS Custom Properties実践⼊⾨フロントエンド交流会 - 2019/07/04ダーシノ(@bc_rikko)
View Slide
⾃⼰紹介ダーシノ(@bc_rikko)さくらインターネットフロントエンドエンジニアファミコン⾵CSSフレームワークNES.css世界ランク 4位※GitHub css-frameworkトピックしらべ
話すこと1. CSS変数の概要2. メリット・デメリット3. CSS変数 vs プリプロセッサ変数4. JavaScriptで操作5. CSS変数 実践⼊⾨CSS Custom Propertiesを「CSS変数」SassやStylusなどの変数を「プリプロセッサ変数」と呼ぶ
概要• CSS Custom Properties(CSS Variables)は、プログラミングの変数と同様の機能をCSSで使う仕組み• CSSプリプロセッサの変数とは違う!(後述)/* 宣⾔ */[selector] {--variable: value;}/* 使⽤ */[selector] {property: var(--variable);}
概要• CSS変数は⼦要素にも影響する• 要素にCSS変数がない場合は、親要素の値を使う.parent {--color: black;--bg-color: white;color: var(--color);background-color: var(--bg-color);}.child {--color: red;color: var(--color);background-color: var(--bg-color);}
プリプロセッサ変数との違い// SCSS$color: black;.message {color: $color;}// コンパイル後.message {color: black;}// CSS変数:root {--color: black;}.message {color: var(--color);}CSS変数 プリプロセッサ変数宣⾔ :rootやセレクタ内のみ どこでもOK変数の値 動的(実⾏時に決定) 静的(変数は消える)構⽂
メリット・デメリット• 疑似クラスやメディアクエリ内で動的に変更できる• JavaScriptで簡単に変更できる• テーマ変更のような操作が楽• 実⾏時にCSS変数の中⾝が決まるので複雑になりやすい• CSS変数がどこに影響するか分かりづらく保守しづらい• CSS変数を書き換えたら他の要素にも影響する• ファイルサイズがちょっと増える(var(̶variable)と書くため)メリットデメリット
CSS変数とプリプロセッサ変数の使い分け• 可能な限りプリプロセッサ変数を使う• 何も考えずにCSS変数に置き換えるのは危険• 特にグローバルで静的な値はプリプロセッサ変数を使う• 擬似クラス、メディアクエリで動的に変更したいなど、 明確な理由があるときはCSS変数を使う
使い分けの具体例$size-s: 1em;$size-m: 1.5em;$size-l: 2em;.btn {--button-size: #{$size-s};}@media screen and (min-width: 600px) {.btn {--button-size: #{$size-m};}}@media screen and (min-width: 1200px) {.btn {--button-size: #{$size-l};}}.btn {font-size: var(--button-size);}グローバルで静的な変数(定数)メディアクエリで動的に変更したいボタンのスタイル
JSでCSS変数を扱うdocument.querySelector(':root').style.setProperty('--button-size', '10px');CSS変数をJavaScriptで動的に変更し、複数のスタイルに⼀括適⽤する | Black Everyday Companyhttps://kuroeveryday.blogspot.com/2018/03/change-css-valiables-by-javascript.html
CSS変数 実践⼊⾨• NES.css@next(次バージョンのProposals段階) https://github.com/nostalgic-css/NES.css/issues/331• スタイルが複雑で、テーマ⾊を変えるのが⼤変• CSS変数をベースにフレキシブルな CSSフレームワークを⽬指す
NES.cssの使いづらいところ①NES.css@nextDefault theme.NES.css@nextIf you want to change thetheme color.<br/>.my-theme {<br/>background-color: #98E800;<br/>}<br/>
根が深い(詳細度問題)NES.css@next<br/>/* NG */<br/>.my-theme .title {<br/>background-color: #98E800;<br/>}<br/>.my-theme .nes-container > .title {<br/>background-color: #98E800;<br/>}<br/>/* OK */<br/>.my-theme<br/>.nes-container.with-title > .title {<br/>background-color: #98E800;<br/>}<br/>詳細度が低くて適⽤されない
CSS変数で解決NES.css@next...<br/>.my-theme {<br/>--background-color: #98E800;<br/>}<br/>// NES.css<br/>.nes-container {<br/>&.with-title {<br/>> .title {<br/>background-color:<br/>var(--background-color);<br/>}<br/>}<br/>}<br/>
CSS変数の副作⽤顧客が必要だったものプログラマのコードNES.css@nextIf you want to change thetheme color.Learn more!<br/>.my-theme {<br/>--background-color: #98E800;<br/>}<br/>⼦要素にも適⽤される
NES.cssの使いづらいところ②NormalMy Theme<br/>.nes-btn.my-theme {<br/>color: white;<br/>background-color: #5676E7;<br/>}<br/>影が変わらない
スタイルが当てづらいMy Theme<br/>.nes-btn.my-theme {<br/>color: white;<br/>background-color: #5676E7;<br/>}<br/>.nes-btn.my-theme::after {<br/>box-shadow:<br/>inset<br/>-4px<br/>-4px<br/>#0E72A3;<br/>}<br/>ユーザーがボーダーのサイズを知る必要がある
CSS変数で解決My Theme<br/>.nes-btn.my-theme {<br/>--color: white;<br/>--background-color: #5676E7;<br/>--shadow-color: #0E72A3;<br/>}<br/>// NES.css<br/>.nes-btn {<br/>color: var(--color);<br/>background-color:<br/>var(--background-color);<br/>&::after {<br/>box-shadow: inset -4px -4px<br/>var(―shadow-color);<br/>}<br/>}<br/>
まとめ• CSS変数は便利だけど過信は禁物• CSS変数をなんとなくで使わない• 闇を⽣み出しやすい• 可能な限り静的な変数のほうが良い• デメリットを理解してから使う
参考サイト✨NES.css@next Proposals - Issue#331https://github.com/nostalgic-css/NES.css/issues/331box-shadow - MDNhttps://developer.mozilla.org/ja/docs/Web/CSS/box-shadowCSS変数をJavaScriptで動的に変更し、複数のスタイルに⼀括適⽤するhttps://kuroeveryday.blogspot.com/2018/03/change-css-valiables-by-javascript.html