Mode sombre : il ne s’agit pas seulement d’inverser les couleurs
Le mode sombre est attendu par les utilisateurs. Sa mise en œuvre naïve entraîne un faible contraste et une fatigue oculaire. Comment concevoir un système de couleurs sémantique qui s'adapte gracieusement.
Pourquoi Maison Code en parle
Chez Maison Code Paris, nous agissons comme la conscience architecturale de nos clients. Nous héritons souvent de stacks “modernes” construites sans compréhension fondamentale de l’échelle.
Nous abordons ce sujet car il représente un point de pivot critique dans la maturité de l’ingénierie. Une mise en œuvre correcte différencie un MVP fragile d’une plateforme résiliente de niveau entreprise.
L’attente des ténèbres
En 2020, le mode sombre était un « agréable à avoir ». En 2025, c’est une exigence. iOS, Android, macOS et Windows prennent tous en charge le mode sombre à l’échelle du système. Si votre utilisateur a son téléphone réglé en mode sombre (pour économiser la batterie ou protéger ses yeux la nuit), et qu’il ouvre votre site Web et est frappé par une explosion de lumière blanche #FFFFFF… Ils ferment l’onglet. C’est physiquement douloureux. Le Mode sombre n’est pas une fonctionnalité ; c’est l’empathie de l’utilisateur.
Pourquoi Maison Code discute du mode sombre
Chez Maison Code, nous nous efforçons de « l’expérience transparente ». Nous veillons à ce que les sites de nos clients respectent automatiquement les préférences système de l’utilisateur (« prefers-color-scheme »). Mais plus important encore, nous comprenons que le mode sombre est un défi de marque. Les marques de luxe misent sur des couleurs spécifiques. Comment traduire « Chanel Black on White » en mode sombre sans perdre l’identité ? Nous effectuons quotidiennement cette traduction sémantique. Nous ne nous contentons pas « d’inverser les couleurs ». Nous « réinterprétons » la marque pour les environnements peu éclairés.
La stratégie d’ingénierie : variables CSS + HSL
(Voir Variables CSS).
L’approche naïve est la suivante :
body.dark {fond : noir ; couleur : blanc ; }.
Cela a l’air terrible. Le noir pur (#000) provoque des « maculages » sur les écrans OLED lors du défilement. Le texte blanc pur (#FFF) sur du noir pur provoque une fatigue oculaire (halation).
L’approche sémantique : Nous définissons les couleurs en utilisant HSL (Teinte, Saturation, Luminosité). Cela nous permet de modifier la légèreté par programme.
:racine {
/* Marque Hue (par exemple Bleu) */
--brand-h : 210 ;
--marques : 100 % ;
/* Mode lumière */
--bg-l : 100 % ;
--texte-l : 10 % ;
--bg-color: hsl(var(--brand-h), 10%, var(--bg-l));
--text-color : hsl(var(--brand-h), 10%, var(--text-l));
}
[data-theme="dark"] {
/* Mode sombre : inversez simplement la luminosité */
--bg-l : 10 % ;
--texte-l : 90 % ;
}
Remarquez que nous n’avons pas simplement choisi “Noir”. Nous avons choisi un « Bleu très foncé » (hsl(210, 10%, 10%)).
Cela préserve la teinte de la marque même en mode sombre. Il semble plus riche et plus haut de gamme que le gris plat.
Implémentation technique : le basculement et le scintillement
La partie la plus difficile du mode sombre est le FOUC (Flash of Unstyled Content) ou Flash of White.
- L’utilisateur charge la page (le serveur envoie du HTML).
- Le navigateur affiche le fond blanc par défaut.
- JS se charge, lit « localStorage » et voit « Dark ».
- JS ajoute la classe
.dark. - La page clignote en noir. Ce flash d’une fraction de seconde détruit l’expérience utilisateur.
Le correctif : un script de blocage dans <head>.
Vous devez injecter un petit script avant le chargement du CSS.
<tête>
<script>
(fonction() {
const stocké = localStorage.getItem('theme');
const system = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (stocké === 'dark' || (!stocké && système)) {
document.documentElement.classList.add('dark');
}
})();
</script>
</tête>
Parce que ce script est dans l’en-tête et qu’il bloque, le navigateur l’exécute avant le premier paint. La page s’affiche initialement comme sombre. Zéro scintillement.
Concevoir pour la profondeur
En mode Lumière, nous utilisons Ombres pour afficher la profondeur (cartes flottantes en arrière-plan). En mode sombre, les ombres sont invisibles (Ombre sombre sur fond sombre). Solution : utilisez Légèreté pour afficher la profondeur.
- Contexte : niveau 0 (le plus sombre).
- Carte : Niveau 1 (Légèrement plus légère).
- Modal : niveau 2 (plus léger).
- Bouton : niveau 3 (le plus léger). Au lieu des “Ombres”, nous utilisons des “superpositions” ou de légers changements de couleur d’arrière-plan.
Images et mode sombre
Les images lumineuses en mode sombre peuvent être choquantes. Conseil : Réduisez légèrement la luminosité et le contraste des images en mode sombre.
[data-theme="dark"] img {
filtre : luminosité (0,8) contraste (1,2) ;
}
Cela permet aux visuels de mieux se fondre avec l’interface sombre.
Le point de vue du sceptique
“Le mode sombre est une mode. J’aime le papier blanc.” Contre-point :
- Batterie : Sur les écrans OLED (iPhone X+), les pixels sombres sont éteints. Le mode sombre permet d’économiser environ 30 % de la durée de vie de la batterie.
- Santé : Réduire l’exposition à la lumière bleue la nuit favorise l’hygiène du sommeil.
- Choix : donnez le choix à l’utilisateur. Si vous forcez le mode Lumière, vous êtes arrogant.
##FAQ
Q : Dois-je utiliser un bouton bascule ? R : Oui. Détectez automatiquement « préfère le schéma de couleurs » en premier, mais autorisez le remplacement par l’utilisateur. Placez-le dans le pied de page ou l’en-tête.
Q : Inverser les logos ?
R : Si votre logo est en texte noir, il disparaît en mode sombre.
Vous avez besoin d’un logo SVG qui hérite de currentColor, ou vous devez échanger la source de l’image (logo-dark.png).
11. Gestion avancée des icônes (SVGcurrentColor)
Arrêtez d’exporter des icônes PNG noires.
Utilisez des SVG en ligne avec fill="currentColor".
Cela fait que l’icône hérite de la couleur du texte de son parent.
Si le texte parent est blanc (mode sombre), l’icône est blanche.
Si le texte parent est noir (Mode Lumière), l’icône est noire.
Cela supprime le besoin de doublons « icon-dark.svg » et « icon-light.svg ».
Un atout. Thèmes infinis.
12. Préférence persistante sans FOUC
Le débat « Cookie » contre « LocalStorage ».
Si vous utilisez le rendu côté serveur (Next.js), « localStorage » n’est pas disponible sur le serveur.
Le serveur affiche donc le mode clair. Le client hydrate le mode sombre. Vaciller.
Solution : Cookies.
Lorsque l’utilisateur change de thème, définissez un cookie theme=dark.
Lisez ce cookie dans middleware.ts ou getServerSideProps.
Injectez <html class="dark"> sur le serveur.
Maintenant, le HTML arrive déjà Dark. Première peinture parfaite.
13. Accessibilité : taux de contraste (WCAG)
Le mode sombre est souvent plus difficile à lire en cas d’astigmatisme.
“Halation” (effet de halo) se produit avec un texte blanc sur fond noir.
Règle : N’utilisez jamais de noir pur (#000000).
Utilisez du gris foncé (#121212 ou similaire). Cela réduit la fatigue oculaire.
Test : utilisez le sélecteur “Contraste” de Chrome DevTools.
Assurez-vous que votre texte répond à la Norme AA (4.5:1).
Souvent, votre « Brand Blue » fonctionne sur le blanc mais échoue sur le noir.
Vous avez besoin de --brand-text-dark (un bleu plus clair) spécifiquement pour le texte en mode sombre.
14. Gestion dynamique des changements de thème du système
L’utilisateur fait passer son Mac de clair à foncé pendant la navigation.
Votre site s’adapte-t-il instantanément ?
Utilisez l’écouteur d’événements change sur matchMedia.
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
const newColorScheme = e.matches ? "sombre" : "clair";
// Mise à jour uniquement si l'utilisateur n'a pas explicitement remplacé la logique
if (!localStorage.getItem('theme')) {
document.documentElement.classList.toggle('dark', e.matches);
}
});
Cela permet cette sensation « magique » où le site Web respire avec le système d’exploitation.
15. Optimisation OLED (True Black vs Grey)
Il y a un débat.
Pure Black (#000000) désactive les pixels. Il économise un maximum de batterie.
Le gris foncé (#121212) améliore la lisibilité du texte et réduit les bavures OLED (traînée violette lors du défilement).
Verdict du code maison : utilisez le gris foncé pour les surfaces (cartes, arrière-plans) et le noir pur pour les bordures ou les espaces négatifs.
Cela vous donne la « Premium Feel » sans les artefacts visuels.
Nous utilisons également meta name="theme-color" pour teinter la barre du navigateur Safari en fonction de votre arrière-plan, créant ainsi une expérience semblable à celle d’une application sans frontières.
16. Détection de thème côté serveur (indices client)
Les cookies sont bons. Les conseils clients sont meilleurs.
Sec-CH-Préfère-Schéma de Couleurs.
Si le navigateur envoie cet en-tête, le serveur sait que l’utilisateur préfère le mode sombre sans lire de cookie.
C’est le Saint Graal.
Il permet de thématiser parfaitement la toute première visite (sans cookie).
Maison Code implémente cette norme de pointe pour nos clients afin de garantir Zero-Flicker sur le premier octet.
17. Pourquoi Maison Code ?
Chez Maison Code, nous ne nous contentons pas de « retourner les couleurs ». Nous repensons l’identité de marque pour les environnements faiblement éclairés. Nous vérifions les rapports de contraste pour garantir la conformité en matière d’accessibilité (ADA/WCAG). Nous implémentons le script “Flicker-Free” pour garantir que vos utilisateurs ne soient jamais flashés. Nous pensons que le mode sombre est un exercice d’empathie. Cela montre que vous vous souciez de la façon dont votre utilisateur consomme votre contenu.
17. Conclusion
Le mode sombre ne consiste pas à changer les couleurs. Il s’agit de vérifier les taux de contraste (WCAG AA), de gérer la perception de la profondeur et de respecter le contexte utilisateur. Bien mis en œuvre, cela ressemble à un intérieur de voiture de luxe la nuit. Mal implémenté, cela ressemble à une invite de commande cassée. Ne laissez pas votre marque paraître brisée 50 % du temps.
Aveugler vos utilisateurs ?
Nous mettons en œuvre un mode sombre système sans scintillement qui respecte la durée de vie de la batterie et les yeux de l’utilisateur. Engagez nos Architectes.