はじめに
この記事は「NTTテクノクロス Advent Calendar 2024(シリーズ2)」の3日目の記事です。
こんにちは。NTT テクノクロスの鈴木雅貴です。社内のあれこれをデザインの力でよくしていくというチームのリーダをしています。個人としては Web 標準技術まわりのスキルで生きており、HTML5 プロフェッショナル認定試験 レベル 1 対策テキスト&問題集 Ver2.5 対応版のいち著者をしています。
今回ですが、2023 年度のアドベントカレンダーで書いたダークモード記事「CSS の light-dark()で Web サイトを楽にダークモード対応させられそう」」記事から状況に変化があったので、そこを踏まえていまダークモード対応するならこう!という話と、あわせてcolor-scheme
に少し踏み込んで調べた話をします。
事前のおことわり
今回紹介する機能は、2024 年 12 月 1 日現在の情報を元にしています。
2024 年度のダークモード対応はこう!
前回記事の紹介どおりなのですが、color-scheme
プロパティとlight-dark()
関数を使いましょう。
例えば、通常(以降ライトモードと書きます)は背景色が白で文字色が黒、ダークモードでは逆にしたい場合は、このように書きます。
:root {
color-scheme: light dark; /* カラースキームとしてライトモード用のlightとダークモード用のdarkを使う */
--text-color: #222; /* ライトモードの文字色 */
--background-color: #f4f4f4; /* ライトモードの背景色 */
}
body {
/* light-dark(A, B) とすると、ライトモードではA、ダークモードではBの色が使われる */
/* ライトモードとダークモードで文字色と背景色が入れ替わる */
color: light-dark(var(--text-color), var(--background-color));
background-color: light-dark(var(--background-color), var(--text-color));
}
こうすると、ライトモードに設定された Web ブラウザでは次のようになります。
ダークモードに設定された Web ブラウザでは背景色と文字色が入れ替わり、
となります。簡単にできますね!
Web ブラウザの対応状況
前回記事を執筆した 2023 年 12 月時点から状況が変わり、すべてのモダンブラウザがcolor-scheme
とlight-dark()
に対応しています。もう安心して使えますね!
- 参考 1: CSS property: color-scheme | Can I use... Support tables for HTML5, CSS3, etc
- 参考 2: types:
<color>
:light-dark()
| Can I use... Support tables for HTML5, CSS3, etc
Web ブラウザのダークモード表示確認方法
Web ブラウザ側でも比較的簡単にダークモードの表示を確かめられるようになりました。
Google Chrome・Microsoft Edge の場合
DevTools を開いた状態で Ctrl+Shift+P(macOS は command+Shift+P)を押すと、コマンドメニューが表示されます。
そこでprefers-color
と入力すると、以下の候補が表示されます。そこから実施したいものを選択してください。
選択肢 | 実施されるもの |
---|---|
CSS prefers-color-scheme: dark をエミュレートする | ダークモードでの表示確認 |
CSS prefers-color-scheme: dark をエミュレートする | ライトモードでの表示確認 |
CSS prefers-color-scheme をトグル | ライトモードとダークモードをトグルする |
Mozilla Firefox の場合
前回記事と変わらず、DevTools の「インスペクター」を選んだ状態で、以下画像右上、ピンクで囲った箇所の三日月型のアイコンをクリックするとダークモード、太陽型のアイコンをクリックするとライトモードの表示を確認することができます。
Safari の場合
DevTools にて「ユーザー環境設定を上書き」のアイコンを選ぶと、外観のカラースキームを選べるツールチップが表示されます。カラースキームの設定を「ライト」にするとライトモード、「ダーク」にするとダークモードの表示を確認することができます。
1 年ですっかり環境が整いましたね!
color-scheme
は何をやっているのか
前述したように、light-dark
とcolor-scheme
を使うと簡単にダークモード対応できるわけですが、@media
とprefers-color-scheme
でダークモード対応していたのと、一体何が違うのでしょうか。気になりましたので、仕様を調べてみました。
@media
とprefers-color-scheme
はユーザーの要求ベース
以下は、@media
とprefers-color-scheme
を使ってダークモード対応している例です。
@media (prefers-color-scheme: dark) {
/* ダークモード時のCSSをここに書く */
}
prefers-color-scheme
はユーザー(Web ブラウザ側)がどういうモードを要求しているかの値です。ライトモードが要求されていればlight
、ダークモードではdark
になります。ユーザーからの要求を見て、それがdark
、すなわちダークモードであった場合の CSS を設定しているわけですね。
つまり、@media
とprefers-color-scheme
を使った方法は、ユーザーの要求を見て、それに従いスタイルを指定しているわけです。
color-scheme
は Web ページからの主張
で、color-scheme
は何をしているかというと、Web ページの側からサポートするカラースキーム(ライトモードかダークモードのどちらか)を主張します。こんな感じです。
/* デフォルトは何もサポートしないことになっている(のでブラウザのデフォルトテーマになる) */
color-scheme: normal;
/* ライトモードのみサポートする */
color-scheme: light;
/* ダークモードのみサポートする */
color-scheme: dark;
/* ライトモードとダークモードの両方をサポートする */
color-scheme: light dark;
そして、light-dark()
でライトモードとダークモードの色を指定します。あとはユーザーからの要求がサポートを主張したモードに含まれていれば、そのモードで設定した色を使う、という仕組みになっています。
ユーザーの要求と Web ページの主張を調整する
この仕組みだと、ユーザーの要求と Web ページの主張が食い違う場合がありえます。このユーザー側の要求(prefers-color-scheme
)と、Web ページ側の主張(color-scheme
)は次のように調整され、モードが決まります。
prefers-color-scheme の値が light | prefers-color-scheme の値が dark | |
---|---|---|
color-scheme: normal | ブラウザのデフォルトテーマ | ブラウザのデフォルトテーマ |
color-scheme: light | ライトモード | ライトモード |
color-scheme: dark | ダークモード | ダークモード |
color-scheme: light dark | ライトモード | ダークモード |
ライトモードとダークモードを切り替えられるようにしておきたい場合は、color-scheme: light dark
としておけばいいわけです。
ただこれだと、color-scheme: light
となっていた場合、ユーザーはダークモードを使うことができません。それでは困る場合もありますので、ユーザーからモードを強制することができるようになっています。例えば Google Chrome では、DevTools から「自動ダークモードを有効にする」ことで、ダークモードを強制することができます。
DevTools の右上三点リーダーから、「その他のツール」→「レンダリング」を選び、
そこから「自動ダークモードを有効にする」を選択すれば、ダークモードを強制できます。
このように、Web ブラウザ側からモード強制があったときには、調整の結果が次の表のように変わります。
prefers-color-scheme の値が light(強制) | prefers-color-scheme の値が dark(強制) | |
---|---|---|
color-scheme: normal | ライトモード(強制) | ダークモード(強制) |
color-scheme: light | ライトモード | ダークモード(強制) |
color-scheme: dark | ライトモード(強制) | ダークモード |
color-scheme: light dark | ライトモード | ダークモード |
このように、Web ブラウザ側から、color-scheme
の設定にかかわらずモードを強制できる仕組みが用意されています。
が、実はcolor-scheme
側でこのモード強制を拒否することもできるようになっています。それがonly
キーワードです。
/* 絶対にダークモードのみ対応 */
color-scheme: only dark;
only
がついたカラースキーマは強制を無視します。ので、このように指定されたページでは、ダークモードしか受け付けません。
このあたりの調整の仕組みを把握しておくと、思い通りにモードが変わらないときにも焦らなくてすみそうです。
前回記事訂正
前回記事でcolor-scheme
の記述に誤りがありましたので、こちらで修正します。(前回記事もあわせて修正しています)
color-scheme
では、Web ページでサポートするカラースキームを宣言することができます。その旨を前回記事でも書いていたのですが、
ここへ新たに別のカラースキームを追加することもできます。hoge を追加するなら color-scheme: light dark hoge;みたいに。
ここの部分が誤りで、任意のカラースキームを追加して宣言することはできません。
CSS Color Adjustment Module Level 1 の color-scheme のところ によりますと、取りうる値はnormal
, light
, dark
, <custom-ident>
(カスタム値), あとはこれらにonly
をつけたものだとあります。カスタム値があるのですが、下の解説にこうあります。
values are meaningless, and exist only for future compatibility, so that future added color schemes do not invalidate the color-scheme declaration in legacy user agents. User agents must not interpret any values as having a meaning; any additional recognized color schemes must be explicitly added to this property’s grammar.
(参考の日本語訳) の値は意味がなく、将来の互換性のためだけに存在する。よって、将来追加される color-scheme よって、従来のユーザーエージェントの color-scheme 宣言が無効になることはない。ユーザーエージェントはを意味あるものとして解釈してはいけない。追加で認識された color-scheme は、このプロパティの文法に明示的に追加される必要がある。
<custom-ident>
は意味がないし、あたらしく追加するなら文法レベルでいれろとあります。ということで、スキームを定義できるという理解は誤りです。失礼いたしました。
おわりに
2024 年 12 月現在のダークモード対応方法として、color-scheme
とlight-dark()
を使った方法を紹介しました。すべてのモダンブラウザで対応していますので、どんどん使っていきましょう!
今までの方法と今回の方法、何が違うの?ということで調べたところ、color-scheme
は Web ページで対応するカラースキーマ(モード)を主張するものだとわかりました。ただ、Web ページ側の主張通りいかない場合もありますので、調整結果を把握しておくとよさそうです。
引き続き、NTTテクノクロス Advent Calendar 2024 (シリーズ2) をお楽しみください!