CSSでのダークモード対応方法と確認方法
CSS でダークモードとライトモード両方のスタイルを作る方法とそのテスト方法です。
ダークモードへの対応
現在(2023.08.15)では、最新の主要ブラウザはすべてprefers-color-scheme
メディアクエリに対応しています(参考)。そのため、対応しているかチェックする方法や、対応していないブラウザへの対応方法はここでは省きます。知りたい方は下に載せている参考記事をみてください。
CSS Variables を使う
ライトモードとダークモードで異なる部分は、”色”だけなので、CSS で使用する色を変数にします。 CSS Variables も最新の主要ブラウザでは対応済みです。
たとえば、body
で設定している色に関する項目を変数に変更するだけです。
body {
color: var(--text);
background-color: var(--background-color);
}
変数をカラーモードごとに変更するためにメディアクエリを使います。
@media (prefers-color-scheme: light) {
:root {
--color: rgb(5, 5, 5);
--background-color: rgb(250, 250, 250);
}
}
@media (prefers-color-scheme: dark) {
:root {
--color: rgb(5, 5, 5);
--background-color: rgb(250, 250, 250);
}
}
変数はファイルを2つに分けたほうがファイルを読み込む順番を制御できるのでおすすめです。
読み込む方法はlink
タグにmedia
を追加します。
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
rel="stylesheet"
href="/light.css"
media="(prefers-color-scheme: light)"
/>
/* light.css: light mode */
:root {
--color: rgb(5, 5, 5);
--background-color: rgb(250, 250, 250);
}
/* dark.css: dark mode */
:root {
--color: rgb(5, 5, 5);
--background-color: rgb(250, 250, 250);
}
CSS がどのモードをサポートしているかをブラウザに教える
ライトモードとダークモードの両方をサポートしている場合は、color-scheme
に以下のように指定します。これを指定することにより、ブラウザにどのモードをサポートしているのか知らせることができます。
:root {
color-scheme: light dark;
}
余談:CSS Variables の命名について
実際にスタイリングに使う変数名は意味づけをしたほうがわかりやすいです。
--black
よりも --text
のほうがライトモードでもダークモードでも意味が通じます。
ただ、色を定義する部分は--black
にしています。その場合は、このような使い方になると思います。
:root {
--black: rgb(5, 5, 5);
--text: var(--black);
}
body {
color: var(--text);
}
各モードの表示の確認はブラウザの Rendering の設定を変更するだけ(Chrome)
Chrome の場合は、Dev Tool を開いて、Rendering
を開きます。
そこに、Emulate CSS media feature prefers-color-scheme
という項目があるので、そこで使用したいカラーモードを選択してください。
このブログでも両方のモードに対応しているので、変更してみてください。
参考記事
画像の扱いなど、この記事では書いていないことも書いてあります。
prefers-color-scheme: 昔馴染みのダークモード
余談:カラーモードを切り替えるスイッチを実装するべきか
ダークモードが出た当時は、ウェブアプリケーション上で変更できるようにしてるものもありましたが、今は不要かなと思います。ユーザーがデバイスごと(もしくはブラウザごと)にすでに選択しているので。モードの ON/OFF を制御するためのスイッチを作成する工数は削減できるし。
それ以上のメリットがある面白いギミックを思いついたりしたら、実装してもいいかもしれません。ただ、「ブラウザの機能は壊さない」が前提だとなかなか難しそう?
そうなると、light or dark ではなく複数のカラーから選択できる機能でいいかなと思います。