ウェブサイトにダークモードを導入しました。
それにあわせて従来のスタイル(ライトモード)も変更しています。
モード切り替えボタン
見出し「モード切り替えボタン」フッタのボタンからモードを切り替えることができます。
2023/02/09 追記 デザイン変更しました。
モードの判定
見出し「モードの判定」ライトモード・ダークモードの判定は初回訪問時は、メディアクエリの prefers-color-scheme
から、OS の設定を参照しています。
ただ、OS の設定のみではなく、モード切り替えボタンからも切り替えられるようにしたかったので、ボタンを選択すると localStorage
でモードの状態が保存されるようにしています。
ページを開くと以下の JS が実行され、これらのモードの判定結果を HTML のルート要素に data-color
属性の値として指定しています。
// モードの判定結果を `data-color` の値に指定
const setColorMode = (mode) => document.documentElement.setAttribute('data-color', mode);
// モードの判定
const getColorMode = () => {
if (localStorage.getItem('color-mode')) {
return localStorage.getItem('color-mode');
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
};
setColorMode(getColorMode());
これによって HTML の data-color
の値が切り替わります。
<!-- ライトモード -->
<html data-color="light">
<!-- ダークモード -->
<html data-color="dark">
スタイルの反映
見出し「スタイルの反映」上記のようにモードの判定の結果を data-color
に指定しているため、CSS では prefers-color-scheme: dark
ではなく、[style*="--color-mode: dark"]
を起点としてスタイルを反映しています。
/* ライトモード */
:root {
--color-primary: #fff;
/* ... */
}
/* ダークモード */
:root[style*="--color-mode: dark"] {
--color-primary: #042020;
/* ... */
}
影響範囲が最小限で済むように、なるべくルート要素の CSS 変数のみで対応できるようにしていますが、それだけでは対応できない部分は個別に調整しました。
反省点としては、CSS の変数名に --color-white
や --color-black
という命名をしていたため、ダークモードのときに把握しづらくなってしまいました。
(見た目ではなく役割で命名すべきでした)
/* ライトモード */
:root {
/* ... */
--color-black: #000;
--color-white: #fff;
/* ... */
}
/* ダークモード */
:root[style*="--color-mode: dark"] {
/* ... */
--color-black: #cfdddd;
--color-white: #1e1e1e;
/* ... */
}
これらの課題も含め、また少しずつ手直ししていきます。