CSSでのダークモード対応方法と確認方法

kaori
kaori

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 ではなく複数のカラーから選択できる機能でいいかなと思います。