ダークモード始めましたか?
エディターをダークモードにしたのがきっかけで、OS、アプリとダークモード始めました!
ダークモードに慣れてしまうと、ダークモード非対応のサイトがめっちゃ眩しい…
というわけで、ユーザーの好みに応じてサイトのカラーモードを切り替えられるボタンを作ってみました!
ちなみに…
私はドラキュラテーマの大ファンです。
エディターだけかと思ったら、たくさんのアプリにも対応してくれています。
いっそのことWindowsのOS自体も対応してほしい!
以下のアプリにドラキュラテーマを適用しています。
- Visual Studio Code
- Chrome
- Firefox
- Thunderbird
- Slack
FileZilla にも対応してくれないかな…
仕様
ブラウザを開いてる間変更したカラーモードを保存するため、セッションストレージを利用します。
- ページ読み込み時のカラーモード
- セッションストレージなし
- OSのカラーモード
- セッションストレージあり
- OSのカラーモードから反転
- セッションストレージなし
- 切り替えボタンをクリック
- OSのカラーモードと異なる
-
html
要素に反転用のclass
を付与 - セッションストレージに反転用の値を保存
-
- OSのカラーモードと同じ
-
html
要素に反転用のclass
が付与されていたら削除 - セッションストレージに反転用の値が保存されていたら削除
-
- OSのカラーモードと異なる
- OSのカラーモードを変更
-
html
要素に反転用のclass
が付与されていたら削除 - セッションストレージに反転用の値が保存されていたら削除
-
HTML
ページ読み込み時、セッションストレージの判定を行う必要があります。
これはページが描画される前に行わないと、OSのカラーモードが一瞬チラついてしまいます。
そのため、head
要素のなるべく上のほうに記述し、実行させます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<script>
// セッションストレージの判定を行う
if (sessionStorage.getItem('colorMode') === 'invert') {
const colorMode = sessionStorage.getItem("colorMode");
document.documentElement.classList.add(colorMode)
}
</script>
</head>
<body>
...
</body>
</html>
Sass
@media
の prefers-color-scheme
メディア特性でライトとダークの時の設定をします。
html
要素に反転用の class
が付与された時の設定もします。
また、切り替えボタンのアイコンの変更も、反転用の class
を継承して設定します。
@mixin light-colors {
--color: #333;
--bg-color: #fff;
}
@mixin dark-colors {
--color: #f2f2f2;
--bg-color: #282a36;
}
@media (prefers-color-scheme: light) {
:root {
@include light-colors;
.btn {
&::before {
content: "\f185";
}
}
&.invert {
@include dark-colors;
.btn {
&::before {
content: "\f186";
}
}
}
}
}
@media (prefers-color-scheme: dark) {
:root {
@include dark-colors;
.btn {
&::before {
content: "\f186";
}
}
&.invert {
@include light-colors;
.btn {
&::before {
content: "\f185";
}
}
}
}
}
body {
background-color: var(--bg-color);
}
.btn {
color: var(--color);
&::before {
font-family: "Font Awesome 6 Free";
}
}
JavaScript
class ColorModeToggleButton {
#colorModeMql
#colorModeBtn
#strageKey
#strageVal
constructor() {
this.#colorModeMql = window.matchMedia('(prefers-color-scheme: dark)')
this.#colorModeBtn = document.getElementById('js-colorModeBtn')
this.#strageKey = 'colorMode'
this.#strageVal = 'invert'
this.#init()
}
#init() {
this.#changeOsColorMode()
this.#clickColorModeBtn()
}
// OSのカラーモードから反転
#invertColorMode() {
sessionStorage.setItem(this.#strageKey, this.#strageVal)
document.documentElement.classList.add(this.#strageVal)
}
// OSのカラーモードに戻す
#resetColorMode() {
sessionStorage.removeItem(this.#strageKey)
document.documentElement.classList.remove(this.#strageVal)
}
// OSのカラーモードの切り替え
#changeOsColorMode() {
this.#colorModeMql.addEventListener('change', () => {
// セッションストレージが設定されている場合は削除(OSの設定優先)
if (sessionStorage.getItem(this.#strageKey)) {
this.#resetColorMode()
}
})
}
// カラーモードボタンをクリック
#clickColorModeBtn() {
this.#colorModeBtn.addEventListener('click', () => {
sessionStorage.getItem(this.#strageKey)
? this.#resetColorMode()
: this.#invertColorMode()
})
}
}
const colorModeToggleButton = new ColorModeToggleButton();
DEMO
See the Pen Dark Mode Toggle Button by Takuya Mori (@taqumo) on CodePen.