Webサイトをダークモードに対応させる方法

1. パソコン・スマホをダークモードに変更

  • Mac の場合 - 「システム環境設定 > 一般 > 外観モード > ダーク」
  • Windows の場合 - 「設定 > 個人用設定 > 色 > 既定のアプリモードを選択 > 黒」
  • iPhone の場合 - 「設定 > 画面表示と明るさ > 外観モード > ダーク」
  • Android の場合 - 「設定 > ディスプレイ > ダークテーマ」(Android10 から対応)

2. デベロッパーツールでダークモードを確認

alt

Chrome ブラウザで **「表示 > 開発/管理 > デベロッパーツール」または、「option + command + I」(win: F12 )**でデベロッパーツールを開きます。

デベロッパーツールを開いたら 「︙」メニューから「Moretool > Rendering」を選択すると Rendering パネルが出てくるので、その中の **「Emulate CSS media feature prefers-color-scheme」**からダークモードの確認できます。

コマンドから開く場合は、**「command + shift + P」( win: Ctrl + Shift + P )**で入力フォームを開いて **「Show Rendering」**と入力します。

3. ダークモードに対応しているかを示すメタタグ

<meta name="color-scheme" content="light dark" />

ダークモードに対応しているかを機械に知らせるメタタグ。追加するとユーザーの配色設定を考慮にいれてレンダリングしてくれるとのこと。

dark mode default styling | web.dev

4. ダークモードを CSS で対応

ダークモードに対応するにはダークモード用のメディアクエリ使用します。ダークモード用のメディアクエリは下記のように記述します。ライトモードはデフォルトのスタイルを使用してダークモードだけ作成でも大丈夫です。

/*ライトモード*/
@media (prefers-color-scheme: light) {
  :root {
    background: #fff;
  }
}

/*ダークモード*/
@media (prefers-color-scheme: dark) {
  :root {
    background: #333;
  }
}

:root - html 要素を表す。詳細度は:root の方が高い。

カスタムプロパティを使用する場合

サイトで同じ値(色や数値)を何度も使用している場合、カスタムプロパティを設定しておくと一括で管理できるようになります。なのでダークモードを設定するときなどはすごく便利です。カスタムプロパティは下記のように記述します。

/*ライトモードのカスタムプロパティ*/
@media (prefers-color-scheme: light) {
  :root {
    --bg-color: #fff;
  }
}

/*ダークモードのカスタムプロパティ*/
@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #333;
  }
}

/*カスタムプロパティの値を使用する*/
body {
  background-color: var(--bg-color);
}

CSS カスタムプロパティ (変数) | MDN

5. ダークモード切り替えスイッチ

ダークモードの切り替えスイッチを作成してみました。ただこのデモはページ移動やリロードしたときの対応はしていません。

デモ

説明

カスタムデータ属性というものを使用しています。カスタムデータ属性は名前の通り、独自の属性を設定できるものです。「data-」からはじまる任意の文字列(属性名)を設定します。

[data-color-mode="dark"] {
  --bg-color: #17223b;
  --font-color: #eee;
  --boder-color: #eee;
}
/*html[data-color-mode='light'] { ... } */

htmlにカスタムデータ属性を下記の記述で付与しています。

document.documentElement.setAttribute("data-color-mode", "dark")

setAttribute - 指定の要素に新しい属性を追加

ユーザー設定がダークモードのときの処理を下記の記述でしています。

if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
  //ダークモードのとき
} else {
  //ライトモードのとき
}

上記の記述と似ていますが、下記は、ダークモードに切り替わったときの処理をしています。

window.matchMedia("(prefers-color-scheme: dark)").addListener(e => {
  if (e.matches) {
    //ダークモードに切り替わったとき
  } else {
    //ライトモードに切り替わったとき
  }
})

6. ダークモード切り替えスイッチ(リロード、ページ移動対応)

ダークモードの切り替えをページ移動などしても保持していたい場合、Derek Kedziora さんが作成したmode-switcher.jsが良いかと思います。Cookie ではなく、sessionStorage で切り替えデータを保存しています。

mode-switcher.js の使い方

mode-switcher.jsから js ファイルを作成します。作成したファイルをフッター直下に読み込みます。

<footer></footer>
<script src="js/mode-switcher.js"></script>

CSS は html と html にカスタム属性を設定しているので、この部分に好みの CSS を設定します。

html,
html[data-theme="light"] {
  /*ライトモード*/
}

html[data-theme="dark"] {
  /*ダークモード*/
}

@media (prefers-color-scheme: dark) {
  html,
  html[data-theme="dark"] {
    /*ダークモード*/
  }

  html[data-theme="light"] {
    /*ライトモード*/
  }
}

切り替えボタンを設置したい場所に下記をコピペします。

<a id="“theme-toggle”" onclick="“modeSwitcher()”"></a>

デフォルトだと上記の a タグの間に下記の「Light Mode」「Dark Mode」文字列が入る仕組みになっています。

document.getElementById("theme-toggle").innerHTML = "Light Mode"
document.getElementById("theme-toggle").innerHTML = "Dark Mode"

この文字列をアイコンフォントに変更したい場合は下記のように js ファイルを変更します。(同じ記述が何箇所かあるのですべて変更)。アイコンフォントは、読み込みの関係でページ移動の際に一瞬ブレる可能性があります。

//アイコンの場合
document.getElementById("theme-toggle").innerHTML = "<i>bedtime</i>"

sessionStorage は文字列しか保存できないので、画像は色々やらないと使用できないようです。

Dark Mode Revisited
GitHub - derekkedziora / dark mode