Perna285FacebookTwitterHatenaPocket進化し続けるCSSの仕様の中でも使い勝手がいいのが、CSS変数。キーカラーやサイズなど、あとから修正するのが面倒な要素はCSS変数を使って工数を減らし、ストレスを軽減しましょう。SassやLessなどのプリプロセッサーは、CSSのコードベースを、メンテナンスしやすい整った状態にするのに役立ちます。変数、mixin(ミックスイン)、loop(ループ)などCSSコーディングに動的な機能を追加すると、繰り返し処理を最小限にし、開発時間を短縮できます。CSSの一部として動的な機能がいくつか登場しています。variables:カスタムプロパティ)はブラウザーの対応状況もとてもよく、すでに利用可能です。「CSS版mixin」は準備段階です。この記事では、CSS開発ワークフローにCSS変数を組み入れる方法を紹介します。スタイルシートのメンテナンス性が向上し、DRYの原則(繰り返しを避けること)に沿ったスタイルシートを実現します。CSS変数とはプログラミング言語を使った経験がある人にとって、変数のコンセプトはおなじみでしょう。変数にはプログラムの動作に必要な値を格納します。変数の値は更新可能です。72つの変数「number1」と「number2」があり、数値「2」と「3」が格納されています。totalも変数で、number1とnumber2の合計「5」が格納されています。変数の値は動的に変更でき、プログラム内の任意の場所で更新された値を使えます。上のスニペットでは、number1の値を4に変更したのち同じ変数(number1とnumber2)を使い、加算しています。結果、格納された数字がtotalが5から7に変わりました。変数のメリットは、値を格納したあと用途に応じて値を変更できることです。別の変数をもつ新しいエンティティをプログラムの各所に追加する必要はありません。値の変更はすべて同じ変数で実行します。CSSは動的な機能を持たない宣言型言語です。CSSに変数が登場すると、理論ずくめで考える人はフロントエンド開発の定義が覆るじゃないかと感じるかもしれませんね。Web関連の技術は生きもののように、取り巻く環境や開発現場のニーズに応じて発展、適応します。CSSも例外ではありません。変数はCSSの世界で注目され、発展し、現実になったのです。このすばらしい新技術をマスターして使いこなすのはとても簡単です。CSS変数を使うメリットCSSで変数を使うメリットは、ほかのプログラム言語で変数を使うのと大きな違いはありません。仕様では、次のように説明されています。CSS変数を使うことで、無意味に見える値に分かりやすい名前をつけられるため、サイズの大きいファイルの読み取りが容易になります。値の変更はカスタムプロパティ(CSS変数)で1回すればよく、変更はその変数が使われている箇所すべてに伝わります。ファイルの編集が簡単になり、エラーも少なくなります。W3C仕様書より以下のように言い換えられます。変数にプロジェクトに関連した分かりやすい名前をつけることにより、コードの管理やメンテナンスがしやすくなります。プロジェクトで原色を編集する場合、CSSカスタムプロパティ--primary-colorの値を変更すればよく、すべての場所のCSSプロパティの値を変更する必要はなくなるのです。CSS変数とプリプロセッサー変数の違いWebサイトのスタイリングで変数の持つ柔軟性を利用する方法は、SassやLessといったプリプロセッサーの活用です。プリプロセッサーで変数を設定すると、関数やループ、算術演算などで使えます。CSS変数に大きなメリットはないのでしょうか?そうとは言えません。CSS変数にはプリプロセッサーで変数を設定するとは違った面がいくつかあります。CSS変数がブラウザーで実行する動的なCSSプロパティなのに対し、プリプロセッサーの変数はCSSコードにコンパイルされるためブラウザーは関与しません。スタイルシートドキュメント内のCSS変数は、インラインスタイル属性やSVGのプレゼンテーション属性で変更したり、JavaScriptで選択、操作したりできるのです。可能性が無限に広がります。プリプロセッサーの変数では実現できません。CSS変数かプロセッサーの変数か、選ぶ必要はありません。CSS変数とプリプロセッサーの変数、両方とも利用しない手はないでしょう。variables)」としています。CSSカスタムプロパティ部分のコードは以下の通りです。#73a4f4;カスタムプロパティは冒頭にハイフンを2つ記述し、通常のCSSプロパティと同様に値を設定します。上のスニペットでは、カラー値にカスタムプロパティ--my-cool-backgroundを設定しました。カスケード変数部分では、var()関数でカスタムプロパティを適用します。var(--my-cool-background)カスタムプロパティのスコープはCSSセレクタ内です。var()はCSSプロパティの実際の値として使えます。<html>要素内のすべてに適用できます)。fooをもつコンテナのbackground-colorプロパティにvar()関数で値を適用でき、背景色がライトブルーになります。var(--my-cool-background)を使ってカスタムプロパティ値を取得し、CSSプロパティに適用するだけで、ライトブルーのカラー値をcolor、border-colorといった複数のHTML要素のカラープロパティに設定できます。複雑化しないうちにCSS変数の命名規則を決めることをおすすめします。var(--my-cool-background);}CSS変数の値に別のCSS変数を設定することも可能です。var(--bottom-color));上のスニペットでは変数--my-gradientを作成し、値を変数--top-colorと--bottom-color双方で設定してグラデーションを実現しています。これで変数の値を変更すれば、グラデーションを修正できます。スタイルシート全体からグラデーションインスタンスをすべてピックアップする必要はないのです。CodePenのライブデモはこちらです。CSS変数にはフォールバック値を1つ以上設定できます。#333);上のスニペットでは「#333」がフォールバック値です。フォールバック値を記述しないと、カスタムプロパティが無効だったり設定されていなかったりすると、代わりに継承値が適用されます。CSS変数では大文字と小文字が区別される通常のCSSプロパティとは異なり、CSS変数では大文字と小文字が区別されます。var(--foo)とvar(--FOO)は別のカスタムプロパティを参照します。CSS変数はカスケードの対象となる通常のCSSプロパティと同様、CSS変数は継承されます。カスタムプロパティを定義し、値をblueとします。blue;}<html>ルート要素内で変数--main-colorが適用された要素はすべて値としてblueを継承します。ほかの要素内でカスタムプロパティに別の値が新しく設定された場合、要素の子要素はすべて新しい値を継承します。</body></html>上のマークアップの最初の段落はグローバル変数--main-colorから値を継承し、カラーは青になります。.alertクラスのdiv内の段落のカラーは、ローカルにスコープ指定された変数--main-colorから値を継承しているため、--main-colorの値の赤になります。コーディングに進みます。SVGでCSS変数を使うにはCSS変数とSVGの相性は抜群です。CSS変数を使って、インラインSVG内のスタイルとプレゼンテーション属性の双方を変更できます。アイコンが配置された親コンテナごとにSVGアイコンのカラーを変更します。変数のスコープを親コンテナに限定し、それぞれに希望の色を設定すると、各コンテナのアイコンは親コンテナの色を継承します。関連するスニペットは以下の通りです。/></svg>上のマークアップでは<symbol>タグで、SVG画像を非表示にします。続いて<use>タグで画像を表示します。この方法では<symbol>要素のIDを使って(#close-icon)参照するだけで、アイコンを複数作成でき、それぞれカスタマイズできます。画像の数だけコードを繰り返し記述するより便利です。Icons(オリジナルのSVGアイコン作成)が参考になります。SVGの「symbol」要素の「circle」要素内、strokeプロパティの値と「text」要素内のfillプロパティの値を見てください。どちらもCSS変数--icon-colorが適用されています。このCSS変数はCSSドキュメント内の:rootセレクタで定義しています。black;}アイコンは次のように表示されます。SVGアイコンを複数のコンテナ要素内に配置し、変数を個々の親要素のセレクタ内にローカル化して別のカラー値を設定すると、スタイルルールを追加しなくてもアイコンの色を変えられます。.successクラスのdiv内に同じアイコンのインスタンスを配置します。</div>.successセレクタ内で値にgreenを設定すると変数--icon-colorをローカル化し、結果を確認します。green;}アイコンが緑になりました。@keyframesアニメーションでCSS変数を使うCSS変数は、通常のHTML要素やインラインSVG要素のCSSアニメーションにも使えます。アニメーションの要素を、ターゲットとするセレクタ内でカスタムプロパティを定義して@keyframesブロック内で関数var()を使ってカスタムプロパティを参照するだけです。SVG画像内で.bubbleクラスの<ellipse>要素をアニメーションしてみましょう。}}CSSのcalc()を使って関数var()と計算しています。コードの柔軟性がさらに向上します。この場合、CSS変数を使うメリットは、適切なセレクタ内で変数の値を変更するだけでアニメーションを微調整できることです。@keyframesで指定したすべての部分に含まれるプロパティを探し出す必要はないのです。完成したデモで試してください。JavaScriptでCSS変数を操作CSS変数は、JavaScriptコードから直接アクセスできます。値が100px、スコープはCSSドキュメント内の.sidebarクラスのCSS変数--left-posがあるとします。100px;}JavaScriptコードから--left-posの値を取得できます。console.log(cssVal);JavaScriptでCSS変数を設定できます。'200px');上のスニペットでは、サイドバー要素用の変数--left-posの値を200pxに設定しています。CSS変数でWebページにインタラクティビティを持たせる方が、状況に応じて多くのクラスを切り替えたり、CSSルール全体を繰り返し記述したりするよりずっと簡単でメンテナンス性が向上します。次のデモを確認してください。modeプロパティや背景色を変更したりできます。Edge(対応しているがバグが多発)を除き、主要ブラウザーはCSS変数に対応しています。対応していないブラウザーを考慮に入れるなら、ダミー条件クエリで@supportsブロックを使いコードを書く方法があります。}}IEやEdgeが@supportsに対応していればこれでOKです。関数var()内のフォールバック値を使えば安全性が高まり、低機能ブラウザーにも柔軟に対応できます。ChromeをはじめとするCSS変数対応ブラウザーでは、<section>要素内のテキストは青になります。IE11はCSS変数に対応していないので、テキストはグレーです。デモを確認してください。CSS変数を使っても、非対応ブラウザーが主流のプロジェクトでは、コードが複雑になり、メンテナンスがちょっとした悪夢になるデメリットがあります。その場合は、PostCSSでcssnextで、CSSコードを非対応ブラウザー用に変換します(JavaScriptのトランスパイラーのようなイメージです)。参考資料ブラウザー対応に関する回避策やおもしろい用途を、CSS変数全般を詳しく知りたい人は、以下の資料を参考にしてください。PernaSitePointのHTML/CSSチャンネルの共同編集者・フロントエンドWeb開発者です。CSSでいろんな手法を試すことを楽しんでいます。フロントエンドのプログラミング指導方法にも興味を持ち、WebのコーディングやWeb関連の執筆をしていないときは、哲学書や散歩、おいしいものを楽しんでいます。