MacOS、Windowsがすでに実装しているように、私はダークモードを実装しています。iOSはネイティブダークモードを導入する予定です。
Safari
、Chrome
、およびFirefox
には、次のCSSメディアルールを使用するネイティブオプションがあります。
@media (prefers-color-scheme: dark) {
body {
color:#fff;
background:#333333
}
これにより、ダークモードに設定されているシステムが自動的に識別され、囲まれたCSSルールが適用されます。
しかしながら;ユーザーがシステムをダークモードに設定している場合でも、特定のWebサイトのライトまたはデフォルトのテーマを好む場合があります。 Microsoft Edge
を(まだ)サポートしていない@media (prefers-color-scheme
ユーザーの場合もあります。最高のユーザーエクスペリエンスを実現するために、これらのユーザーがこれらのケースでダークモードとデフォルトモードを切り替えられるようにしたいと思います。
HTML5またはJavaScriptを使用して、これを実行できるメソッドはありますか?私が試したコードを含めますが、これを実装するための情報を見つけることができませんでした!
@JimmyBanksが提供するソリューションを採用し、1)チェックボックスをテキストボタンに切り替え、2)OSテーマの変更時に自動テーマ切り替えを追加しました。
CSSは変更されていません。明るいテーマは:root
に、暗いテーマは[data-theme="dark"]
に保存されています。
:root {
--color_01: #000;
--color_02: #fff;
--color_03: #888;
}
[data-theme="dark"] {
--color_01: #fff;
--color_02: #000;
--color_03: #777;
}
<head>
JSにはいくつかの編集があり、いくつかの省略とdata-theme
ステートメントの後続のJSブロックへの移動が含まれています。
var theme = 'light';
if (localStorage.getItem('theme')) {
if (localStorage.getItem('theme') === 'dark') {
theme = 'dark';
}
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
theme = 'dark';
}
次に、JSの2番目のブロックの編集と関連するHTMLを示します。 theme_switch
はテーマを切り替えますが、theme_OS
はサイトのテーマをOSテーマの変更で自動的に更新します。
var theme;
function theme_apply() {
'use strict';
if (theme === 'light') {
document.getElementById('theme_readout').innerHTML = 'Dark';
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light');
} else {
document.getElementById('theme_readout').innerHTML = 'Light';
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}
}
theme_apply();
function theme_switch() {
'use strict';
if (theme === 'light') {
theme = 'dark';
} else {
theme = 'light';
}
theme_apply();
}
var theme_OS = window.matchMedia('(prefers-color-scheme: light)');
theme_OS.addEventListener('change', function (e) {
'use strict';
if (e.matches) {
theme = 'light';
} else {
theme = 'dark';
}
theme_apply();
});
<a onclick="theme_switch()">Theme: <span id="theme_readout"></span></a>
改善のためのご提案がございましたら、ぜひお知らせください。
私のソリューション(無線入力の3つのオプション:ダーク、システム、ライト)のJimmyBanksおよびMeanderbiltソリューションの適応:
少し冗長だと思いますが、頭を巻くのに少し苦労しました
const themeSwitches = document.querySelectorAll('[data-color-theme-toggle]')
function removeColorThemeLocalStorage() {
localStorage.removeItem('color-theme')
}
function saveColorTheme(colorTheme) {
if (colorTheme === 'system') {
removeColorThemeLocalStorage()
return
}
localStorage.setItem('color-theme', colorTheme)
}
function applyColorTheme() {
const localStorageColorTheme = localStorage.getItem('color-theme')
const colorTheme = localStorageColorTheme || null
if (colorTheme) {
document.documentElement.setAttribute('data-color-theme', colorTheme)
}
}
function themeSwitchHandler() {
themeSwitches.forEach(themeSwitch => {
const el = themeSwitch
if (el.value === localStorage.getItem('color-theme')) {
el.checked = true
}
el.addEventListener('change', () => {
if (el.value !== 'system') {
saveColorTheme(el.value)
applyColorTheme(el.value)
} else {
removeColorThemeLocalStorage()
document.documentElement.removeAttribute('data-color-theme')
}
})
})
applyColorTheme()
}
document.addEventListener('DOMContentLoaded', () => {
themeSwitchHandler()
applyColorTheme()
})
html {
--hue-main: 220;
--color-text: hsl(var(--hue-main), 10%, 25%);
--color-text--high-contrast: hsl(var(--hue-main), 10%, 5%);
--color-link: hsl(var(--hue-main), 40%, 30%);
--color-background: hsl(var(--hue-main), 51%, 98.5%);
}
@media (prefers-color-scheme: dark) {
html.no-js {
--color-text: hsl(var(--hue-main), 5%, 60%);
--color-text--high-contrast: hsl(var(--hue-main), 10%, 80%);
--color-link: hsl(var(--hue-main), 60%, 60%);
--color-background: hsl(var(--hue-main), 10%, 12.5%);
}
}
[data-color-theme='dark'] {
--color-text: hsl(var(--hue-main), 5%, 60%);
--color-text--high-contrast: hsl(var(--hue-main), 10%, 80%);
--color-link: hsl(var(--hue-main), 60%, 60%);
--color-background: hsl(var(--hue-main), 10%, 12.5%);
}
<div class="color-scheme-toggle" role="group" title="select a color scheme">
<p>saved setting: <span class="theme-readout">...</span></p>
<input type="radio" name="scheme" id="dark" value="dark" aria-label="dark color scheme"> <label for="dark">dark</label>
<input type="radio" name="scheme" id="system" value="system" aria-label="system color scheme" checked="system"> <label for="system">system</label>
<input type="radio" name="scheme" id="light" value="light" aria-label="light color scheme"> <label for="light">light</label>
</div>