
ダークモードに対応させる方法をまとめてみる。ついでに他のカラーテーマにもできるようにしてみる。
経緯
ダークモードに対応したWebサービス、増えてますね。
私もPCとかスマホのテーマはダークにしていて、ダークモードがメインになってます。ずっとダークモード使っていると、白い画面がちょっとずつまぶしくなってきます。
自分が運営しているWebサイトもまぶしいなと感じてきたので、ダークモードに対応させました。その時に調べた内容や、使った方法なんかをまとめておきます。
実装方法1(メディアクエリ)
色々と調べてみると色々な方法で実装しているところがありますね。
一番簡単な方法がCSSのメディアクエリを使う方法です。
@media (prefers-color-scheme: dark) {
body {
background-color: #000;
color: #fff;
}
}
@media (prefers-color-scheme: dark)でシステムのテーマがダークモードの時に適応させるものです。
その中にダークモードの色合いを設定すれば、ダークモードに対応できます。JavaScriptは不要で色を設定しているCSSに追加すればいいので、既存のサイトでも簡単に追加できます。
実装方法2(クラス指定)
メディアクエリを使う方法は簡単でいいのですが、システムのテーマに依存して、サイト上では設定ができません。システムはダークモードにしていても、使うサイトは元の色で使いたい場合もあるかと思います。
そんな場合はJavaScriptを利用してクラス付与によるダークモードを実現させます。
CSSにダークモード用のクラスを設定しておきましょう。ここではdark-modeにしています。
.dark-mode {
background-color: #000;
color: #fff;
}
あとは、JavaScriptでページを開いたときに、クラスを付与するようにすればいいだけです。
if(window.matchMedia('(prefers-color-scheme: dark)').matches){
document.body.classList.add('dark-mode');
}
window.matchMedia('(prefers-color-scheme: dark)').matchesでダークモードを判定しています。ダークモードの場合にdark-modeクラスをbodyに付与しています。
そして、どこかにチェックボックスか何かをおいて、サイト上で切り替えられるようにするといいですね。
<input type="checkbox" name="dark-mode" id="btn-dark-mode">
const btn = document.querySelector("#btn-dark-mode");
btn.addEventListener("change", () => {
if (btn.checked === true) {
document.body.classList.add("dark-mode");
} else {
document.body.classList.remove("dark-mode");
}
});
このままだとページ移動すれば設定が消えるので、ローカルストレージやキャッシュにチェックの結果を保存しましょう。そして保存した結果をテーマ設定時に読みだします。
const btn = document.querySelector("#btn-dark-mode");
btn.addEventListener("change", () => {
if (btn.checked === true) {
document.body.classList.add("dark-mode");
localStorage.setItem('dark-mode-settings', 'dark');
} else {
document.body.classList.remove("dark-mode");
localStorage.setItem('dark-mode-settings', 'light');
}
});
if(localStorage.getItem('dark-mode-settings')==='dark') {
document.body.classList.add("dark-mode");
}else if (localStorage.getItem('dark-mode-settings')==='light') {
//light modeの時
}else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.classList.add("dark-mode");
}
ローカルストレージやキャッシュの設定を優先して、保存されてなかった場合はシステムの方を優先するといいですね。
select boxでカラーテーマを選べるようにしてもいいでしょう。
実装方法3(CSS変数)
クラスを指定して、色を変えるのでもいいのですが、色を設定しているところが多くなるとCSSがカオスになってしまいます(経験済み)
なので私はCSS変数で管理するのがいいかと思います。
:root {
--color-body-font: #000000;
--color-body-bg: #ffffff;
}
:root[mode="dark"] {
--color-body-font: #ffffff;
--color-body-bg: #000000;
}
:root[mode="blue"] {
--color-body-font: #ffffff;
--color-body-bg: #2ca3db;
}
body{
color: var(--color-body-font);
background-color: var(--color-body-bg);
}
:rootに色のCSS変数を書いておいて、ダークモードの時にその変数を上書きするようにすればいいです。
最初に使う色を決めておけば他のところで変える必要もないし、どこかの色を全部変えたくなっても色の設定部分を変えればそれだけで済みます。また色テーマを複数にしても管理しやすくなります。
・読みだし
const localTheme = localStorage.getItem('color-mode-settings');
if(localTheme) {
document.documentElement.setAttribute('mode', localTheme);
}else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('mode', 'dark');
}}
・セレクト部
<select name="color" id="js-color">
<option value="light">ライト</option>
<option value="dark">ダーク</option>
<option value="blue">ブルー</option>
</select>
・セレクト変更時
const color_select = document.querySelector('#js-color');
color_select.addEventListener("change", () => {
document.documentElement.setAttribute('mode', color_select.value);
localStorage.setItem('color-mode-settings', color_select.value);
});
こんな感じで色テーマを増やしても大丈夫です。
雑感
優れたサービスでも色が気に入らなくて、使っているとイライラしてきたりするので、そういうときに自分が好きな色にできるといいなと思いました。
ただ、自社のブランドカラーもあるので、Webデザイナーに近い人ほどこういうのはしたくないんだろうなぁとも思いました。
ブランドカラーをきっちり決めていると、他の色との調和がとれない場合もあるので、なかなか厳しそうですね。あと古くからやっているところだと色の管理がカオス化している気がするので、こちらも厳しそう。
新しく作るところは、きちんと色を管理して自分の好きな色で設定できるようにするのがよさそう。
参考
良ければサポートお願いします。サポート費用はサーバー維持などの開発費に使わせていただきます。