# Mode sombre dans un thème WordPress : prefers-color-scheme et bascule manuelle

> Variables CSS, media query prefers-color-scheme, bouton de bascule persistant en localStorage et le cas délicat des images sur fond clair.

- Auteur : Clément Hadrot
- Publié le : 2021-02-04
- Mis à jour le : 2021-02-04
- Catégorie : Thèmes
- URL : https://wpmoderne.dev.wordpress-developpement.fr/themes/mode-sombre-theme-wordpress-prefers-color-scheme/

## L’essentiel

- Variables CSS pour centraliser les couleurs des deux thèmes
- prefers-color-scheme pour respecter le réglage système
- localStorage pour mémoriser le choix manuel

Depuis que Twenty Twenty-One a intégré un mode sombre respectant les préférences système, plusieurs clients de l'agence ont demandé la même chose sur leur thème sur mesure. Le domaine viticole des Trois Chênes en particulier : son site, très photo, gagnait à proposer un fond sombre le soir sans pour autant l'imposer à tout le monde. Ce tutoriel construit un mode sombre complet, du système de variables CSS jusqu'au bouton de bascule qui mémorise le choix de l'utilisateur.

L'idée directrice tient en une phrase : ne jamais dupliquer les règles CSS pour chaque thème, mais centraliser toutes les couleurs dans des variables que l'on réassigne selon le contexte.

## Centraliser les couleurs dans des variables CSS

Tout part d'un jeu de variables définies sur `:root`, qui couvrent l'ensemble des couleurs utilisées dans le thème : fond, texte, bordures, accent. Aucune couleur ne doit être écrite en dur ailleurs dans la feuille de style :

```
:root {
	--color-bg: #ffffff;
	--color-text: #1a1a1a;
	--color-border: #e0ded9;
	--color-accent: #7a2e2e;
}

body {
	background-color: var(--color-bg);
	color: var(--color-text);
}

.site-header {
	border-bottom: 1px solid var(--color-border);
}
```

## Respecter le réglage du système avec prefers-color-scheme

> L'essentiel à retenir : Variables CSS pour centraliser les couleurs des deux thèmes ; prefers-color-scheme pour respecter le réglage système ; localStorage pour mémoriser le choix manuel

La media query `prefers-color-scheme` permet de lire la préférence définie au niveau du système d'exploitation ou du navigateur de l'utilisateur, sans aucune action de sa part. Il suffit de redéfinir les mêmes variables à l'intérieur de cette media query :

```
@media (prefers-color-scheme: dark) {
	:root {
		--color-bg: #171512;
		--color-text: #ede8e0;
		--color-border: #3a3632;
		--color-accent: #d98c5f;
	}
}
```

Comme toutes les règles du thème utilisent déjà les variables et jamais de couleurs en dur, cette seule media query suffit à basculer l'intégralité de l'habillage visuel. C'est ce qui rend l'approche si économique : pas besoin de dupliquer chaque sélecteur CSS pour une version sombre.

## Ajouter une bascule manuelle qui prime sur le système

Se fier uniquement au réglage système ne suffit pas : certains visiteurs veulent choisir indépendamment de leur préférence système, par exemple pour comparer les deux rendus. La solution consiste à ajouter un attribut sur la balise `html`, contrôlé par un bouton, qui prend le pas sur la media query :

```
:root[data-theme="dark"] {
	--color-bg: #171512;
	--color-text: #ede8e0;
	--color-border: #3a3632;
	--color-accent: #d98c5f;
}

:root[data-theme="light"] {
	--color-bg: #ffffff;
	--color-text: #1a1a1a;
	--color-border: #e0ded9;
	--color-accent: #7a2e2e;
}
```

Ces deux blocs, plus spécifiques qu'une media query, s'appliquent dès que l'attribut `data-theme` est présent sur `<html>`, quel que soit le réglage du système. Côté JavaScript, le bouton de bascule écrit cet attribut et mémorise le choix :

```
const toggle = document.querySelector( '.theme-toggle' );
const root = document.documentElement;

const saved = localStorage.getItem( 'agence-theme' );
if ( saved ) {
	root.setAttribute( 'data-theme', saved );
}

toggle.addEventListener( 'click', () => {
	const current = root.getAttribute( 'data-theme' ) === 'dark' ? 'light' : 'dark';
	root.setAttribute( 'data-theme', current );
	localStorage.setItem( 'agence-theme', current );
} );
```

### Le cas des images sur fond clair

Sur le site du domaine viticole, plusieurs photos de flacons avaient été détourées sur fond blanc pur : parfaitement discrètes en mode clair, elles formaient un rectangle blanc criant une fois le mode sombre activé. La correction la plus simple, sans retoucher chaque image, a consisté à appliquer un léger fond neutre et une ombre portée douce derrière les images détourées en mode sombre uniquement :

- Repérer les images à fond blanc plutôt que les photographies pleines, généralement via une classe dédiée dans le contenu.
- Leur appliquer un `background-color` clair et un `border-radius` léger, visibles seulement quand `data-theme="dark"` est actif.
- Vérifier au cas par cas les visuels avec transparence, souvent les plus problématiques.

> Un mode sombre qui ignore le réglage système frustre une partie des visiteurs ; un mode sombre qui ignore le choix manuel frustre les autres. Les deux mécanismes doivent coexister, l'un par défaut, l'autre en priorité.

## En résumé

Avec des variables CSS bien centralisées, une media query `prefers-color-scheme` pour le comportement par défaut et un attribut `data-theme` piloté en JavaScript pour la bascule manuelle persistée en `localStorage`, un mode sombre complet tient dans une cinquantaine de lignes de CSS et une dizaine de lignes de JavaScript. Les variations de styles propres à l'éditeur de site, encore balbutiantes à ce stade de WordPress, resteront un sujet à part entière.
