【ITニュース解説】Beyond Light/Dark Mode: Implementing Dynamic Themes with CSS Custom Properties
2025年09月22日に「Dev.to」が公開したITニュース「Beyond Light/Dark Mode: Implementing Dynamic Themes with CSS Custom Properties」について初心者にもわかりやすく解説しています。
ITニュース概要
Webサイトでライト/ダークだけでなく、ユーザー好みの動的なテーマを実装するには、CSS Custom Properties(CSS変数)が効果的だ。CSS変数はJavaScriptで実行時に値を変更でき、これにより背景色や文字色などのデザインを簡単に切り替えられる。保守性・拡張性の高いテーマシステムを構築できる。
ITニュース解説
現代のWebデザインにおいて、単にライトモードとダークモードを切り替えるだけでは、もはやユーザーの期待に応えきれない状況がある。ユーザーは、システムの標準設定だけでなく、自身の個人的な好み、例えば落ち着いた青色や、視認性を高めるためのハイコントラスト、あるいは好きなブランドの色など、より多様な選択肢に基づいてインターフェースが変化することを望んでいる。このようなユーザーの要望に応え、動的で柔軟なテーマシステムを構築するための鍵となるのが、CSSカスタムプロパティ、別名CSS変数と呼ばれる強力なCSS機能である。
CSSカスタムプロパティは、従来のSASSやLESSのようなプリプロセッサ変数とは異なる特徴を持つ。プリプロセッサ変数はコンパイル時に静的な値に変換されるため、一度定義されるとWebページがブラウザで表示された後にその値を変更することはできない。しかし、CSSカスタムプロパティはブラウザ上で「生きた」変数として機能する。これは、Webページがロードされた後でも、JavaScriptを使ってその値を動的に更新できることを意味する。この特性こそが、テーマ切り替え機能の理想的な基盤となるのだ。
CSSカスタムプロパティの主な利点はいくつか挙げられる。まず、「動的な更新」が可能である。ある変数の値を変更すると、その変数を使用しているすべてのHTML要素に、その変更が瞬時に反映される。次に「スコープ」の概念がある。変数はWebサイト全体で利用可能なグローバルな範囲で定義できるだけでなく、特定のコンポーネントや要素の内部でのみ有効なローカルな範囲でも定義できる。これにより、柔軟かつきめ細やかなデザインシステムを構築することが可能になる。最後に「カスケードと継承」の原則に従う点が挙げられる。これは他の標準的なCSSプロパティと同じように動作するため、スタイルを管理する上で予測可能で強力な方法を提供する。
では、実際に動的テーマを実装する手順を追って解説する。最初のステップは、テーマのカラーパレットをCSSカスタムプロパティとして定義することである。これまでのように、color: #333;のように具体的な色コードを直接記述するのではなく、色の「目的」を表すセマンティックな変数名を使用する。例えば、--color-primary(主要な色)、--color-background(背景色)、--color-text(文字色)といった具合だ。これらの変数は通常、HTMLドキュメントのルート要素である:rootセレクタに定義され、Webページ全体で利用可能にする。色値をRGB形式(例: 56, 73, 214)で定義することで、後からJavaScriptで透明度(アルファ値)を簡単に制御できるようになるという利点もある。
これらの定義された変数を実際のCSSルールの中で使用するには、var()関数を用いる。例えば、body { background-color: rgb(var(--color-background)); color: rgb(var(--color-text)); }のように記述する。この記述により、背景色や文字色が直接的な色コードではなく、変数によって指定される。ボタンやカードといった個別のコンポーネントのスタイルも同様に、背景色や枠線の色などにこれらの変数を適用することで、一貫性のあるデザインを保ちながら、後からの変更にも対応しやすくなる。例えば、.buttonの背景色にはrgba(var(--color-primary), 1)のように記述し、ボタンがホバーされた際にはrgba(var(--color-primary), 0.8)とすることで、主要な色の透明度だけを変えて変化を表現できる。
次のステップは、複数のテーマ定義を作成することだ。単なるライトモードとダークモードの切り替えも、このシステムの一種として考えることができる。複数のテーマを定義する方法はいくつかあるが、最も一般的なのはCSSのクラス名やデータ属性を利用して、特定の変数値を上書きすることだ。例えば、:rootでデフォルトのライトテーマの変数を定義し、.theme-darkというクラスセレクタ内で、背景色や文字色などの変数をダークテーマ用の値に再定義する。これにより、HTMLの<body>要素や<html>要素に.theme-darkクラスが適用されると、その要素以下で定義された変数(ダークテーマ用の値)が優先的に適用されるようになる。
データ属性(例: [data-theme="dark"])を使用する方法も非常に有効で、その明確さと特定性から好まれることが多い。[data-theme="dark"]セレクタ内でダークテーマ用の変数を、[data-theme="high-contrast"]セレクタ内でハイコントラストテーマ用の変数を定義する。このアプローチの素晴らしい点は、.cardや.buttonといった個々のコンポーネントのCSSスタイルは一切変更する必要がないことである。これらのコンポーネントは常に変数を参照しているため、HTML要素に適用されるテーマクラスやデータ属性が変更されるだけで、自動的に新しいテーマに適応するのだ。
そして、このシステムに魔法をかけるのがJavaScriptによるテーマの切り替えである。テーマの適用は、HTMLのルート要素(<html>要素、JavaScriptではdocument.documentElementでアクセスできる)に、対応するクラス名を追加したり、データ属性の値を変更したりするだけのシンプルな操作で実現できる。例えば、ユーザーがテーマ選択ドロップダウンで「ダーク」を選択した場合、JavaScriptはdocument.documentElement.setAttribute('data-theme', 'dark');というコードを実行するだけで、Webページ全体のテーマをダークモードに切り替えることができる。さらに、ユーザーが選択したテーマの好みをブラウザのlocalStorageに保存しておけば、次回ページを訪れた際にその設定を読み込み、自動的に同じテーマを適用することが可能になる。これにより、ユーザーは毎回テーマを選択し直す手間が省け、より快適な体験が得られる。
このコンセプトをさらに発展させると、ユーザーがテーマの一部を自分で定義できるような機能も実装できる。例えば、Webページ全体で使用されるプライマリカラーをユーザー自身がカラーピッカーを使って自由に選択できるようにする機能だ。HTMLには<input type="color" id="primary-color-picker" value="#3849d6">のようなカラーピッカー要素を配置する。JavaScriptでは、このカラーピッカーの入力イベントを監視し、ユーザーが新しい色を選択するたびに、その色のHEX値をRGB形式に変換する。そして、document.documentElement.style.setProperty('--color-primary', newRgbValue);というJavaScriptコードを使って、CSSカスタムプロパティである--color-primaryの値を動的に更新する。これにより、ユーザーが選んだ色が即座にWebページ全体に適用され、自分だけのカスタマイズされたUIを楽しむことができる。このカスタムカラーもlocalStorageに保存しておくことで、再訪問時に設定が維持される。
CSSカスタムプロパティをこのように活用することで、単にライト/ダークモードのような二者択一の選択肢を超えた、より表現力豊かなUIを構築するための強固な基盤を築ける。このテーマシステムは、すべてのデザイン要素(トークン)が一箇所に論理的に定義されているため、非常に保守しやすい。新しいテーマを追加する際も、既存のCSSブロックに新しい変数の定義を追加するだけで簡単に拡張できる。そして何よりも、ユーザーが自分の好みに合わせてWebインターフェースをパーソナライズできるため、エンゲージメントの向上やアクセシビリティの改善にも繋がる。このアプローチは、Google、Apple、GitHubといった大手企業が採用しているモダンなデザインシステムの根幹を成すものであり、これを自身のプロジェクトに導入することで、より動的で、柔軟で、ユーザーフレンドリーなWebインターフェースを構築する第一歩となるだろう。