ダークモードの6つのレベル(2024)
(cssence.com)- ブラウザーの基本機能から JavaScript メディアクエリ まで、ダークモード実装の範囲を段階的に広げていく 8段階の区分 を整理
- 最も単純な方法は
<meta name="color-scheme" content="light dark">またはcolor-scheme: light darkの宣言だけで、ユーザーのカラースキーム設定 に従う構成 - より高い段階では
light-dark()関数、@media (prefers-color-scheme: dark)、スキーム別の 分離スタイルシート により、色だけでなく画像や影まで幅広く調整可能 - ユーザーのシステム設定に従うだけでなく、Automatic・light・dark の3つの選択肢を提供するスイッチャーを構成でき、
:has()と実際の meta 要素 を基準にテーマを判定可能 - Safari の アクセシビリティ上の限界 や、印刷時の
prefers-color-schemeの動作観察まで含まれており、最近の CSS 機能だけでもライト・ダークモードの内蔵が容易になったことが分かる
ダークモードの段階別実装
-
Level 1: Barebone
- CSS を1行も書かなくても light/dark の区別 を有効化でき、文書の head に
<meta name="color-scheme" content="light dark">を追加するだけでブラウザーがユーザーの カラースキーム設定 に従い始める content属性の項目順には理論上意味があり、カラースキーム設定を明示していないユーザーには、空白区切りの一覧の先頭の値が適用される- 現在の OS 設定にはカラースキームを選択しないオプションがないため、実際には OS 設定と一致するスキームに落ち着く
contentに単一の値だけを指定することもでき、この場合はユーザー設定を考慮せずそのスキームを強制適用する- この meta タグは、ある程度は次の段階の CSS 方式に対応する HTML 側の方法 として機能する
- CSS を1行も書かなくても light/dark の区別 を有効化でき、文書の head に
-
Level 2: Basic
- CSS では
html { color-scheme: light dark; }の宣言で ライト/ダークモードの区別 を適用できる - すでに DOM に meta タグがあるならこの宣言は不要で、HTML を制御できるならブラウザーが CSS を解析する前から指示を把握できる meta タグの使用が推奨される
- どちらの方法でも、ユーザーエージェントのデフォルトスタイルと、そこに含まれる ライト/ダークモード を利用できるようになる
- ここに CSS を追加しつつ、主に CSS system colors の使用に絞れば、かなり整ったデザインを実現できる
- meta タグが常に文書全体に適用されるのに対し、CSS の
color-scheme宣言はルート要素以外の場所にも設定でき、この違いにより追加の活用余地がある
- CSS では
-
Level 3: Benign
- 比較的新しく追加された CSS の
light-dark()色関数 により、単純なライト/ダークモード調整が可能 - 例では
background-color: light-dark(black, white);とcolor: light-dark(white, black);のように使い、最初の引数はライトモードに、2番目の引数はダークモードに適用される - 引数には実際の色を直接入れることもできるし、色として解釈される custom properties を入れることもできる
- この記事全体の中では、この段階だけが執筆時点では ブラウザー対応 がまだ十分ではない
- 比較的新しく追加された CSS の
-
Level 4: Bold
- 従来の
@media (prefers-color-scheme: dark)メディアクエリ でダークモード切り替えを実装できる lightとdarkのどちらを問い合わせても、単なる色変更にとどまらない 最大レベルのカスタマイズ が可能- ダークモードで画像をフィルターで低彩度にしたり、ボックスシャドウをアウトラインに置き換えたりする調整もすべて可能
- 従来の
-
Level 5: Bisectional
- メディアクエリは HTML でも使え、
link要素のmedia属性に入れて スキーム別スタイルシート を分離できる - 例として
light.cssとdark.cssをそれぞれprefers-color-scheme: lightとprefers-color-scheme: darkに結びつける方法が示されている - カスタマイズ範囲が大きい場合は専用ファイル構成が適しており、ブラウザーはクエリに一致しない CSS ファイルを無視できるため、ダウンロード対象を1つ減らせる可能性がある
- メディアクエリは HTML でも使え、
-
Level 6: Ballistic
- JavaScript では
window.matchMedia('(prefers-color-scheme:dark)')で カラースキームのメディアクエリ を使える - 他のメディアクエリと同じ方法でライトまたはダークスキームかどうかを問い合わせ、その結果に基づいて任意の処理を行える
- 実際の実装では、前段までの手法を1つだけに固定せず 組み合わせて適用 できる
- JavaScript では
ユーザースイッチャーと高度なパターン
-
Level 7: Beyond
- ユーザーのシステム設定だけに依存せず、color scheme switcher を構築できる
- このスイッチャーは単純な真偽値ではなく、初期デフォルトとして
prefers-color-schemeに従う Automatic モードが必要 - その上にスイッチャーを載せると、ユーザーは Automatic、light、dark の 3つのモード から1つを選べる
-
Level 8: Beguiling
- Level 7 のスイッチャー実装では、一般に HTML 要素へ
.darkクラスやdata-theme="dark"のような属性を追加する方式がよく使われる - その代わりに
:has()を使って、実際の<meta name="color-scheme" content="dark">の有無を直接問い合わせることができる - 例では
html:has(meta[name="color-scheme"][content="dark"])セレクターの下で、--color-bg、--color-textのような CSS 変数 をダークモード用の値に設定している - 別途クラスやデータ属性がなくても、実際の meta 要素 を基準にテーマを判定できる
- Level 7 のスイッチャー実装では、一般に HTML 要素へ
追加の議論と観察
-
CSS Naked Day での観察
- スタイルを外して訪れたほぼすべてのサイトで ダークモード不在 が目立ち、これがダークモードの段階分けにつながった
- 新しいサイトを最初から構築して新しいスタイルを書く場合、最近の CSS 機能により ライト/ダークモードの内蔵 が非常に容易になったとの言及を含む
-
Safari のアクセシビリティ問題
- 比較的最近まで Safari はダークモードで アクセシブルなリンク色 を提供していなかったという指摘を含む
- 以前の CSS Naked Day ではこの問題を見つけ、meta タグを削除してライトカラースキームだけを使った経験にも触れている
- その後 meta タグを再び追加したが、旧バージョンの Safari 利用者には アクセシビリティ低下 が生じうることを認識している
- Safari のダークモードではテキストボックスに 見える境界線がない ことも確認された
- ユーザーエージェントのスタイルだけでは、正しいセマンティック HTML を使っていても完全なアクセシビリティは保証できず、今後の CSS Naked Day でも十分なスタイルを維持する方法を考えている
-
印刷と
screen and条件- Bisectional の例で
screen and ...を使った理由として、プリンター向けの除外 を意図したことに触れている - テーマ非依存のコアスタイルシートや専用の印刷スタイルシートが別にあると仮定し、プリンターでダークモードがインクを多く使う可能性があるため、安全のため分離しようという判断が示されている
- 実際のテストでは、システムのダークモードを有効にした状態で印刷しても黒い文字と白い紙だけが出力され、ブラウザーは印刷時にそのダークモードスタイルを適用していないようだと観察された
- 追加テストでは、印刷プレビューでは
prefers-color-schemeが常に light と報告され、Firefox と Chromium で確認された - 黒い紙と白いインクを使うプリンターがあれば残念だ、という冗談めいた言及も含まれる
- Bisectional の例で
1件のコメント
Hacker Newsのコメント
userContent.cssでbackground-colorを指定するやり方が悪くないと思う