WebDesigner's Memorandumウェブデザイナーの備忘録

js-cookieでウェブサイトのダークモード表示設定をユーザーごとに保存しておく方法

js-cookieでウェブサイトのダークモード表示設定をユーザーごとに保存しておく方法

少し前にブログをリニューアルして、そのときに一緒にダークモードの対応を行いました。

ただ、人によっては「システム環境設定に依存しないで、常にダークモードの方がいい!」人や「逆にライトモードの方が見やすい!」という人もいると思い、個別に設定できるように変更してみました。

今後デザインは変えていく予定ですが、メニュー右上の「表示設定」をクリックすると設定モーダルが表示されます。

ダークモード設定変更のモーダル

このラジオボタンを選択すると、それぞれのモードに固定されます。

  • ライト
  • ダーク
  • ナイト
  • システム設定に合わせる(デフォルト)

ちなみに「ライトモード」と「ダークモード」以外に「ナイトモード」という表示も追加していて、これは深夜暗い部屋でも見やすいように、色を全体的に暗くして画像の輝度も下がります。

今回はこれの実装方法についてまとめておきます。
ダークモード自体の実装方法は有名ですが、それを保存する方法についてはあまり見かけなかったので、ぜひ参考にしてください。

ダークモードの対応

そもそもまずはダークモードの対応が必要です。

CSS変数を利用して、ライトモード(通常)時と@media (prefers-color-scheme: dark) {}を使って、ダークモード時の色を設定します。

:root{
  --c-primary: #0076b5;
  --c-secondary: #17C2C7;
  --c-background-base: #F7F9FB;
  --c-background-primary: #FFF;
  --c-background-secondary: #F0F2F5;
  --c-text-base: #555;
  --c-text-lighter: #676767;
  --c-text-link: #0076b5;
}
@media (prefers-color-scheme: dark) {
  :root{
    --c-primary: #EBCB1A;
    --c-secondary: #FF178D;
    --c-background-base: #2B2B2B;
    --c-background-primary: #313131;
    --c-background-secondary: #242424;
    --c-text-base: #EAEAEA;
    --c-text-lighter: #B7B7B7;
    --c-text-link: #0076b5;
  }
}

これでライトモードとダークモードの指定はできましたが、このままだとメディアクエリでのみの設定になるので、bodyに特定classが付いたときにも変数が変わるようにしておきます。

body.dark-mode{
  --c-primary: #0076b5;
  --c-secondary: #17C2C7;
  --c-background-base: #F7F9FB;
  --c-background-primary: #FFF;
  --c-background-secondary: #F0F2F5;
  --c-text-base: #555;
  --c-text-lighter: #676767;
  --c-text-link: #0076b5;
}

js-cookieの導入

js-cookieを使うと、JavaScriptでCookieの登録や取得が簡単にできます。こちらから読み込みます。

js-cookieでCookieの登録

Cookieを登録したい場合はCookies.set('Cookie名', 値);で登録できます。

Cookies.set('darkmode', darkModeVal);

Cookieを取得したい場合はCookies.get('Cookie名');で取得できます。

Cookies.get('darkmode');

あとはラジオボタンでどこがチェックされているのかを判定するのと、判定に応じてbodyにclassを追加するだけです。

let getDarkModeVal = function () {
  let radios = document.getElementsByName('darkmode');
  for (let i = 0; i < radios.length; i++) {
    if (radios[i].checked) {
      return radios[i].id;
    }
  }
}

let setDarkModeVal = () => {
  let darkModeVal = getDarkModeVal();
  switch (darkModeVal) {
    case 'light':
      document.body.classList.add("light-theme");
      document.body.classList.remove("dark-theme");
      document.body.classList.remove("night-theme");
      break;
    case 'dark':
      document.body.classList.remove("light-theme");
      document.body.classList.add("dark-theme");
      document.body.classList.remove("night-theme");
      break;
    case 'night':
      document.body.classList.remove("light-theme");
      document.body.classList.remove("dark-theme");
      document.body.classList.add("night-theme");
      break;
    default:
      document.body.classList.remove("light-theme");
      document.body.classList.remove("dark-theme");
      document.body.classList.remove("night-theme");
      break;
  }
  Cookies.set('darkmode', darkModeVal);
}

const darkMode = Cookies.get('darkmode');
if (darkMode) {
  document.getElementById(darkMode).checked = true;
} else {
  document.getElementById('system').checked = true;
}

// チェックした時の挙動
let radios = document.getElementsByName('darkmode');
for (let i = 0; i < radios.length; i++) {
  radios[i].addEventListener('change', () => {
    setDarkModeVal();
  });
}

PHPでCookieに合わせてclassを追加する

いまのままだと、ページが表示された後にJavaScriptが読み込まれてclassが付くまでの間はライトモードが表示されてしまいます。

一瞬ライトモードが表示されて、そのあとダークモードになったりするのはむしろ目がチカチカしてしまうので、Cookieが設定されてある場合はPHPで最初からclassを付けておくようにしましょう。

PHPでやることはCookieの取得のみで、isset( $_COOKIE['Cookie名'] )で取得ができるので、取得したあとは条件分岐でclassの中身を設定します。

<?php if ( isset( $_COOKIE['darkmode'] )){
  if($_COOKIE['darkmode'] == 'light'){
    $darkModeClass = 'light-theme';
  }elseif($_COOKIE['darkmode'] == 'dark'){
    $darkModeClass = 'dark-theme';
  }elseif($_COOKIE['darkmode'] == 'night'){
    $darkModeClass = 'night-theme';
  }
}?>
<body class="<?php echo $darkModeClass ?>">

これで、ダークモードのCookieが設定されてある場合は最初からダークモードのclassが付いた状態で表示されます。

著者について

プロフィール画像

サイトウ マサカズ@31mskz10

1997年生まれ。2016年から専門学校でデザインについて勉強。卒業後は神戸の制作会社「N'sCreates」にウェブデザイナーとして入社。このブログでは自分の備忘録も兼ねて、ウェブに関する記事や制作環境を効率的に行うための記事を書いています。

Twitterをフォロー Facebookでいいね