初期表示では、OS側からのダークモードの設定を行い、サイト内からもダークモードの設定をできるようにしてみる。
動作
https://vcss.netlify.com
これの右上のトグルボタン
OSからのダークモード設定
OSからのダークモードの設定はCSSでメディアクエリを使用する。
:root {
--base3: #{$base3};
--base2: #{$base2};
--base1: #{$base1};
--base0: #{$base0};
}
@media (prefers-color-scheme: dark) {
:root {
--base3: #{$base03};
--base2: #{$base02};
--base1: #{$base01};
--base0: #{$base00};
}
}
これで、ダークモードだった場合は、@media内の設定を読み込むようになる。
サイト内からのダークモード設定
サイト内での設定では、トグルボタン等から変更を受けた時に、HTMLタグにクラス等を付与して切り替える。
:root {
--base3: #{$base3};
--base2: #{$base2};
--base1: #{$base1};
--base0: #{$base0};
&[data-theme="dark"] {
--base3: #{$base03};
--base2: #{$base02};
--base1: #{$base01};
--base0: #{$base00};
}
}
@media (prefers-color-scheme: dark) {
:root {
--base3: #{$base03};
--base2: #{$base02};
--base1: #{$base01};
--base0: #{$base00};
&[data-theme="light"] {
--base3: #{$base3};
--base2: #{$base2};
--base1: #{$base1};
--base0: #{$base0};
}
}
}
データ属性が付与されたら、既存の変数を上書きする。
<template>
<div>
<input type="checkbox" v-model="checked" @change="setScheme"/>
</div>
</template>
<script>
export default {
data() {
return {
checked: false
};
},
created() {
// ローカルストレージチェック
if (localStorage.colorThema === "light") {
this.checked = true;
} else if (localStorage.colorThema === "dark") {
document.documentElement.setAttribute("data-theme", "dark");
} else if (!window.matchMedia("(prefers-color-scheme: dark)").matches) {
// darkモードではない時トグルボタンを動かす
this.checked = true;
}
},
methods: {
setScheme: function () {
// ローカルストレージに保存
localStorage.colorThema = this.checked ? "light" : "dark";
}
},
watch: {
checked: function(check) {
// HTMLタグのdata属性に設定
if (check) {
document.documentElement.setAttribute("data-theme", "light");
} else {
document.documentElement.setAttribute("data-theme", "dark");
}
}
}
};
</script>
checkboxに合わせてHTMLタグにdata属性を加えたりローカルストレージに入れたり。
課題
data属性にカラースキーマが設定されている状態で、OSの設定からカラースキームを変更されても表示は変更されなくなってしまう