Dark mode et accessibilité : Le guide complet
En Bref : L'essentiel à retenir
- Le dark mode peut améliorer l'accessibilité pour certains utilisateurs (photophobie, fatigue oculaire) mais dégrader les contrastes si mal implémenté.
- Respecter prefers-color-scheme permet de synchroniser avec les préférences système de l'utilisateur pour une meilleure UX.
- Les contrastes doivent être vérifiés dans les deux modes, certaines couleurs passent en light mais échouent en dark.
- Le bouton de bascule doit être accessible au clavier avec un état clair (aria-pressed ou aria-checked).
Le dark mode est partout. De iOS à Windows, des réseaux sociaux aux IDE de développement. Mais implémenter un mode sombre accessible n'est pas aussi simple qu'inverser le noir et blanc.
Pourquoi le dark mode est un enjeu d'accessibilité ?
Le mode sombre n'est pas qu'une préférence esthétique. Il répond à de vrais besoins :
| Besoin | Bénéfice du dark mode |
|---|---|
| Photophobie | Réduction de la luminosité globale |
| Migraines | Moins de stimulation lumineuse |
| Fatigue oculaire | Moins de contraste écran/environnement sombre |
| Basse vision | Texte clair sur fond sombre parfois plus lisible |
| Autisme | Réduction de la surcharge sensorielle |
[!NOTE] Attention : pour certains utilisateurs dyslexiques, le dark mode peut réduire la lisibilité. D'où l'importance d'offrir le choix.
Les règles de base
1. Respecter prefers-color-scheme
Le CSS permet de détecter la préférence système de l'utilisateur :
/* Mode clair par défaut */
:root {
--bg-color: #ffffff;
--text-color: #1a1a1a;
}
/* Mode sombre si préférence système */
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #1a1a1a;
--text-color: #f5f5f5;
}
}
Pourquoi c'est important ?
- L'utilisateur a déjà fait son choix au niveau système
- Pas besoin de chercher un bouton de bascule
- Cohérence avec les autres applications
2. Offrir une bascule manuelle
Certains utilisateurs veulent un mode différent de leur système (ex: dark mode système mais site en light). Proposez un toggle :
<button
id="theme-toggle"
aria-pressed="false"
aria-label="Activer le mode sombre"
>
<span class="icon-sun" aria-hidden="true"></span>
<span class="icon-moon" aria-hidden="true"></span>
</button>
const toggle = document.getElementById('theme-toggle');
toggle.addEventListener('click', () => {
const isDark = document.documentElement.classList.toggle('dark');
toggle.setAttribute('aria-pressed', isDark);
toggle.setAttribute('aria-label',
isDark ? 'Activer le mode clair' : 'Activer le mode sombre'
);
localStorage.setItem('theme', isDark ? 'dark' : 'light');
});
3. Mémoriser la préférence
// Au chargement de la page
const savedTheme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (savedTheme === 'dark' || (!savedTheme && prefersDark)) {
document.documentElement.classList.add('dark');
}
Les pièges des contrastes
Le problème des couleurs "intermédiaires"
Une couleur peut être conforme en light mode mais pas en dark mode :
| Couleur | Sur blanc (#fff) | Sur noir (#000) |
|---|---|---|
| Bleu #3b82f6 | 4.53:1 | 4.63:1 |
| Gris #6b7280 | 4.54:1 | 4.57:1 |
| Rouge #ef4444 | 4.00:1 | 5.17:1 |
| Vert #22c55e | 2.39:1 | 8.57:1 |
Solution : Définir des palettes de couleurs distinctes pour chaque mode.
:root {
--error-color: #dc2626; /* 4.63:1 sur blanc */
}
.dark {
--error-color: #f87171; /* 4.52:1 sur #1a1a1a */
}
Éviter le noir pur
Un fond #000000 pur avec du texte #ffffff pur crée un contraste de 21:1. C'est techniquement conforme mais fatigant pour les yeux.
Recommandation : Utilisez un gris très sombre (#1a1a1a ou #121212) et un blanc cassé (#f5f5f5 ou #e5e5e5).
/* Trop contrasté */
.dark {
background: #000000;
color: #ffffff;
}
/* Plus confortable */
.dark {
background: #18181b; /* Zinc-900 */
color: #fafafa; /* Zinc-50 */
}
Les éléments à adapter
1. Les images
Certaines images (logos, schémas) ont un fond transparent qui devient invisible en dark mode.
/* Inverser les images en dark mode si nécessaire */
.dark img.invertible {
filter: invert(1) hue-rotate(180deg);
}
Ou mieux, fournir deux versions :
<picture>
<source srcset="/logo-dark.svg" media="(prefers-color-scheme: dark)">
<img src="/logo-light.svg" alt="Logo">
</picture>
2. Les ombres
Les ombres classiques (box-shadow: 0 4px 6px rgba(0,0,0,0.1)) sont invisibles sur fond sombre.
:root {
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.dark {
--shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.5);
/* Ou utiliser des bordures */
}
3. Les formulaires
Les champs de formulaire avec background: white cassent en dark mode.
input, select, textarea {
background: var(--input-bg);
color: var(--input-text);
border: 1px solid var(--input-border);
}
:root {
--input-bg: #ffffff;
--input-text: #1a1a1a;
--input-border: #d1d5db;
}
.dark {
--input-bg: #27272a;
--input-text: #fafafa;
--input-border: #52525b;
}
Critères RGAA concernés
| Critère | Impact dark mode |
|---|---|
| 3.2 Contraste texte | À vérifier dans les deux modes |
| 3.3 Contraste graphiques | Icônes, bordures à adapter |
| 10.1 Pas de CSS unique | Préférences utilisateur respectées |
| 10.7 Focus visible | Le style focus doit rester visible |
Checklist dark mode accessible
-
prefers-color-schemeest respecté - Un bouton de bascule est disponible
- Le bouton a un
aria-pressedouaria-checked - La préférence est mémorisée (localStorage)
- Tous les contrastes sont ≥ 4.5:1 dans les deux modes
- Les images à fond transparent sont adaptées
- Les ombres restent visibles (ou remplacées par des bordures)
- Les formulaires ont des styles dark mode
- Le focus est visible dans les deux modes
- Pas de flash au chargement (thème appliqué avant le rendu)
Éviter le flash de mode incorrect
Le "flash of unstyled content" (FOUC) se produit quand la page s'affiche en light puis bascule en dark.
Solution : Script bloquant dans le <head> :
<head>
<script>
(function() {
const theme = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (theme === 'dark' || (!theme && prefersDark)) {
document.documentElement.classList.add('dark');
}
})();
</script>
</head>
Outils de test
- RGAA Checker : Scannez votre site dans les deux modes
- Chrome DevTools : Rendering > Emulate CSS prefers-color-scheme
- Notre calculateur de contraste : Testez vos palettes
Conclusion
Le dark mode accessible n'est pas qu'une inversion de couleurs. Il demande une réflexion sur les palettes, les contrastes et l'expérience utilisateur. Bien fait, il améliore l'accessibilité pour de nombreux utilisateurs. Mal fait, il peut l'aggraver.
Testez vos deux modes avec RGAA Checker pour vous assurer que vos contrastes sont conformes dans tous les cas.
Guides RGAA associés
Pour aller plus loin sur les sujets abordés dans cet article, consultez nos fiches techniques :
Chaque champ de formulaire doit avoir une étiquette (label) qui lui est liée explicitement.
Chaque image porteuse d'information doit avoir une alternative textuelle pertinente via l'attribut alt. Les images décoratives doivent avoir un attribut alt vide.
Le contraste entre la couleur du texte et la couleur de son arrière-plan doit être suffisamment élevé (4.5:1 pour le texte normal, 3:1 pour le grand texte).
Articles similaires
Votre site est-il conforme ?
Ne prenez pas de risques avec l'accessibilité. Lancez un audit complet de votre site en quelques minutes et obtenez un rapport détaillé des corrections à apporter.