以前、CSSでダークモードに対応する方法についてご紹介しましたが、JavaScript を使って動的に切り替えたい場合には少し工夫が必要です。この記事では、JavaScript を活用してライトモード・ダークモードを切り替える機能を実装する方法を解説します。

LINE着せかえ「回るお寿司」販売中!

CSS によるダークモード実装のおさらい

まずは、CSS だけでダークモードを実装する方法を確認しておきましょう。

@media (prefers-color-scheme: dark){} を使用する

以下のように@media (prefers-color-scheme: dark){}を使用して CSS を記述すると、ユーザーのシステム設定(ブラウザなどの設定)に応じてダークモード用のスタイルが適用されます。

:root {
  --text-color: black;
  --body-bg-color: white;
}

@media (prefers-color-scheme: dark) {
  :root {
    --text-color: white;
    --body-bg-color: black;
  }
}

body {
  color: var(--text-color);
  background: var(--body-bg-color);
}

この例では、システム設定でダークモードが選択されている場合は CSS 変数の値が変わり、bodyの文字色が白、背景色が黒に切り替わります。

light-dark() 関数を使用する

CSS の:root疑似クラスでcolor-schemeを設定したうえでlight-dark()関数を使用すると、ユーザーのシステム設定に応じてダークモード用の値が適用されます。

:root {
  color-scheme: light dark;
}

body {
  color: light-dark(black, white);
  background: light-dark(white, black);
}

JavaScript で切り替える際に必要な処理

JavaScript でライトモード・ダークモードを切り替える際、@media (prefers-color-scheme: dark){}を使用しているかlight-dark()関数を使用しているかによって必要な処理が変わってきます。

@media (prefers-color-scheme: dark){} を使用している場合

@media (prefers-color-scheme: dark){}で指定されたスタイルは、JavaScript で動的に適用させることができません。そのため、JavaScript での切り替えを行うためには、メディアクエリの使用をやめ、通常のセレクタでスタイルを指定する形に変更する必要があります。

その際は、以下のようにモード判別のためのdata属性をhtmlに付与し、それをセレクターに使用してスタイルを設定する方法が一般的です。

<html lang="ja" data-color-scheme="dark">

セレクターがhtmlに変更されるため、:root疑似クラスで CSS 変数を定義している場合は、:root {}の外に出す必要があります。

:root {
  --text-color: black;
  --body-bg-color: white;
}

/* @media (prefers-color-scheme: dark) → html[data-color-scheme="dark"] に変更 */
html[data-color-scheme="dark"] {
  /* :root {} は外す */
  --text-color: white;
  --body-bg-color: black;
}

body {
  color: var(--text-color);
  background: var(--body-bg-color);
}

これにより、JavaScript でhtmldata属性の変更を行うとライトモード・ダークモードの切り替えが可能になります。

light-dark() 関数を使用している場合

light-dark()関数を使用している場合は、:root疑似クラスに設定されているcolor-schemeの値をlightのみ、もしくはdarkのみに変更することでライトモード・ダークモードの切り替えが可能です。

このcolor-schemeは、「このサイトではこのカラーのテーマを使用します」という宣言のようなもので、この値をどちらか片方のみにすることで、強制的にそのモードに切り替えることができます。

JavaScript によるダークモード切り替え機能の実装

さて、いよいよここからは、切り替え機能の実装について解説していきます。

切り替えボタンの設置

まずは、以下のように、ライトモード・ダークモードの切り替えボタンを HTML に設置します。

<div id="colorSchemeSelector">
  <button name="light">ライトモード</button>
  <button name="dark">ダークモード</button>
</div>

ボタン押下時の切り替え処理

次に、ボタンを押したときの処理を JavaScript で記述します。

window.addEventListener("DOMContentLoaded", function () {
  // :root 疑似クラスを取得
  const root = document.querySelector(":root");
  // ボタン要素を取得
  const colorSchemeButtons = document.querySelectorAll("#colorSchemeSelector button");

  for(let i = 0; i < colorSchemeButtons.length; i++) {
    // ボタン押下時の処理を設定
    colorSchemeButtons[i].addEventListener("click", function() {
      // 選択したモードの情報を localStorage に保存
      localStorage.setItem('selectedColorScheme', this.name);
      // color-scheme の値を書き換え
      root.style.setProperty("color-scheme", this.name);
      // html に data-color-scheme を設定
      document.querySelector("html").dataset.colorScheme = this.name;
    });
  }
});

color-schemedata属性の書き換え以外に、選択したモードが次回以降のページ読み込み時にも反映されるようにするための情報をlocalStorageに保存しています。

HTML の <head> 内にページ読み込み時の切り替えコードを記述

ページ読み込み時に、システム設定のprefers-color-schemelocalStorageの設定を反映するためのコードを<head>内に記述します。

このコードは、システム設定のモードとサイト上で選択されたモードに差異があった場合のチラつきを防止するため、可能な限り<head>内の上のほうに記述するのを推奨します。

<script>
(function() {
  // :root 疑似クラスを取得
  const root = document.querySelector(":root");
  // localStorage に保存されたモードの情報を取得
  const localSetting = localStorage.getItem("selectedColorScheme");
  // ユーザーのシステム情報を取得
  const systemPrefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
  // localStorage に情報があればそちらを優先、なければシステム情報のモードを使用
  const colorScheme = localSetting ? localSetting : (systemPrefersDark ? "dark" : "light");

  // color-scheme の値を書き換え
  root.style.setProperty("color-scheme", colorScheme);
  // html に data-color-scheme を設定
  document.querySelector("html").dataset.colorScheme = colorScheme;
})();
</script>

このコードにより、

  • localStorageに保存された設定を最優先
  • localStorageに値がなければシステム設定のprefers-color-schemeを使用する、といったロジックでモードが適用されます。

JavaScript によるダークモード切り替えのサンプル

以下は、JavaScript によるダークモード切り替えのサンプルです。ボタンを押すとライトモード・ダークモードが切り替わるのが確認できます。

See the Pen Untitled by YUTSUZO (@YUTSUZO) on CodePen.

終わりに

JavaScript を使用すれば、CSS のみでは出来なかったライトモード・ダークモードの切り替え機能を実現できます。ダークモード対応はユーザー体験を向上させる重要な要素です。ぜひ今回紹介した方法を活用し、ご自身のウェブサイトに実装してみてください!