J'implémente un mode sombre, comme l'ont déjà fait macOS, Windows et iOS devrait introduire un mode sombre natif.
Il existe une option native pour Safari
, Chrome
et Firefox
, en utilisant la règle de média CSS suivante:
@media (prefers-color-scheme: dark) {
body {
color:#fff;
background:#333333
}
Cela identifiera automatiquement les systèmes qui sont définis sur les modes sombres et appliquera les règles CSS jointes.
Toutefois; même si les utilisateurs peuvent avoir leur système réglé en mode sombre, il se peut qu'ils préfèrent le thème clair ou par défaut d'un site Web spécifique. Il y a aussi le cas de Microsoft Edge
utilisateurs qui ne prennent pas (encore) en charge @media (prefers-color-scheme
. Pour la meilleure expérience utilisateur, je veux m'assurer que ces utilisateurs peuvent basculer entre les modes sombre et par défaut pour ces cas.
Existe-t-il une méthode pour cela, éventuellement avec HTML5 ou JavaScript? J'inclurais le code que j'ai essayé, mais je n'ai pu trouver aucune information sur l'implémentation de celui-ci!
A pris la solution fournie par @JimmyBanks et 1) a transformé la case à cocher en bouton de texte à bascule, et 2) a ajouté le changement de thème automatique lors du changement de thème du système d'exploitation.
CSS est inchangé, avec des thèmes légers stockés dans le :root
et thèmes sombres stockés sous [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;
}
Le <head>
JS a subi quelques modifications, notamment quelques omissions et le déplacement de data-theme
instruction au bloc JS suivant:
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';
}
Et voici l'édition du deuxième bloc de JS, ainsi que le code HTML associé. theme_switch
bascule le thème, tandis que theme_OS
met automatiquement à jour le thème du site avec les modifications apportées au thème du système d'exploitation.
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>
Veuillez me faire savoir si vous avez des suggestions d'amélioration!
Ma Solution (3 options d'entrées radio: dark, system, light) adaptation de JimmyBanks et Meanderbilt Solution:
c'est un peu verbeux, je suppose, mais j'ai eu un peu de mal à m'enrouler autour de la tête
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>