2019/12/09

CSS Custom Propertiesと良好な関係を築くための戦略


この記事はCSS Advent Calendar 2019 9日目の記事です。

CSS Custom Properties、ときにCSS変数やCSS Variablesとも呼ばれているプロパティがある。昨今のダークモード等のテーマ変更の需要の高まりとともに、多くのウェブサイトで使われるようになった。

たとえば、CSS Custom Propertiesを使うと以下のようにCSSだけでOSのテーマを判別し、ダークモード表示ができる。
/* Default / Light Theme */
:root {
  --color: black;
  --background-color: white;
}

/* Dark Theme */
@media (prefers-color-scheme: dark) {
  :root {
    --color: white;
    --background-color: black;
  }
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

他にも以下のようにスタイルの管理がしやすくなる。
/* Before */
a {
  color: #0000EE;
}
a:visited {
  color: #800080;
}
a:active {
  color: #FF0000;
}

a.grayscale {
  color: LightSlateGray;
}
a.grayscale:visited {
  color: Silver;
}
a.grayscale:active {
  color: LightSteelBlue;
}
/* After */
a {
  --link: #0000EE;
  --link-visited: #800080;
  --link-active: #FF0000;
}

a.grayscale {
  --link: LightSlateGray;
  --link-visited: Silver;
  --link-active: LightSteelBlue;
}

a {
  color: var(--link);
}
a:visited {
  color: var(--link-visited);
}
a:active {
  color: var(--link-active);
}
参考: Patterns for Practical CSS Custom Properties Use | CSS Tricks


すごい、、、すごく便利そう!!


しかし、一見便利そうなCSS Custom Propertiesも使い方によっては闇を生み出してしまう。
ということで、当記事ではNES.css(CSSフレームワーク)開発で得た<知見>を元に、CSS Custom Propertiesのメリット・デメリットを理解し良好な関係を築く方法を紹介する。


CSS Custom Propertiesの基礎


CSS Custom Propertiesの基本構文は、--variable: valueのようにプロパティの頭に--をつけて宣言する。使用するときはvar(--variable)のようにvarを使って値を参照する。
/* 宣言 */
[selector] {
  --variable: <value>;
}

/* 使用 */
[selector] {
  property: var(--variable);
}

スコープが存在するので、子要素にも影響するし、対象セレクタに変数定義がなければ親要素の値を参照する。
<div class="parent">
  <div class="child">
  </div>
</div>
.parent {
  --color: black;
  --bg-color: white;

  /* color: black; */
  color: var(--color);
  /* background-color: white; */
  background-color: var(--bg-color);
}

.child {
  --color: red;

  /* color: red; */
  color: var(--color);
  /* background-color: white; */
  background-color: var(--bg-color);
}


CSSプリプロセッサの変数との違い


SassやStylus、LessなどのCSSプリプロセッサでも変数が使える。しかし、CSS Custom Propertiesとは根本的に違うものだと理解してほしい。
CSS Custom PropertiesCSSプリプロセッサ変数
構文
:root {
  --color: black;
}
.message {
  color: var(--color);
}
$color: black;
.message {
  color: $color;
}

// コンパイル後
.message {
  color: black;
}
宣言セレクタ内のみどこでも可
変数の値動的(実行時に決定)静的(変数は消える)

「変数の値」の違いが大きいため、何も考えずにCSSプリプロセッサ変数をCSS Custom Propertiesに置き換えようとは思わないでほしい。その理由を次で説明する。



CSS Custom Propertiesのメリットとデメリット


たしかにCSS Custom Propertiesはフレキシブルで便利だ。しかい、ただでさえ崩壊しやすいCSSに闇を注入してしまうのは避けたい。だから使う前にメリット・デメリットを理解しておきたい。

メリット


デメリット

  • 実行時に変数の中身が決まるので複雑になりやすい
  • 変更がどこに影響するかわかりづらい
  • ファイルサイズがちょっと増える(var(--color)のように指定するため)


CSS Custom Propertiesと良好な関係を築く戦略


  • 可能なかぎりCSSプリプロセッサ変数を使う
    • 特にグローバルで静的な値とか
  • 「擬似クラス(:hoverなど)やメディアクエリで動的に変更したい」のような明確な理由があるときだけCSS Custom Propertiesを使う
    • 何も考えずに使うのは危険

具体例を紹介する。
ウィンドウサイズによってボタンのフォントサイズを動的に変更するスタイルの例だ。
// グローバルで静的な変数
$size-s: 1em;
$size-m: 1.5em;
$size-l: 2em;

// デフォルトスタイル
.btn {
  --btn-size: #{$size-s};
}

// メディアクエリで--btn-sizeを上書きする
@media screen and (min-width: 600px) {
  .btn {
      --btn-size: #{$size-m};
  }
}
@media screen and (min-width: 1200px) {
  .btn {
      --btn-size: #{$size-l};
  }
}

// ボタンのスタイル
.btn {
  font-size: var(--btn-size);
}


まとめ


  • CSS Custom Propertiesは便利だけど過信は禁物
  • なんとなくで使わない
    • 闇を生み出しやすいため
    • 可能なかぎりプリプロセッサ変数を使うほうが良い
    • デメリットを理解する

実践的な使い方


CSS Custom Properties実践入門というスライドを公開している。このスライドの11ページ以降でCSSフレームワーク(NES.css)を例にとり実践的なCSS Custom Propertiesの使い方を紹介しているので、ぜひ読んでみてほしい。



以上

written by @bc_rikko

0 件のコメント :

コメントを投稿