Aller au contenu principal
Design & Contenu3 décembre 20257 min

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).
Dark ModeDesignRGAACSSAccessibilité

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 :

BesoinBénéfice du dark mode
PhotophobieRéduction de la luminosité globale
MigrainesMoins de stimulation lumineuse
Fatigue oculaireMoins de contraste écran/environnement sombre
Basse visionTexte clair sur fond sombre parfois plus lisible
AutismeRé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 :

CODE
/* 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 :

CODE
<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>
CODE
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

CODE
// 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 :

CouleurSur blanc (#fff)Sur noir (#000)
Bleu #3b82f64.53:14.63:1
Gris #6b72804.54:14.57:1
Rouge #ef44444.00:15.17:1
Vert #22c55e2.39:18.57:1

Solution : Définir des palettes de couleurs distinctes pour chaque mode.

CODE
: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).

CODE
/* 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.

CODE
/* Inverser les images en dark mode si nécessaire */
.dark img.invertible {
  filter: invert(1) hue-rotate(180deg);
}

Ou mieux, fournir deux versions :

CODE
<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.

CODE
: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.

CODE
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èreImpact dark mode
3.2 Contraste texteÀ vérifier dans les deux modes
3.3 Contraste graphiquesIcônes, bordures à adapter
10.1 Pas de CSS uniquePréférences utilisateur respectées
10.7 Focus visibleLe style focus doit rester visible

Checklist dark mode accessible

  • prefers-color-scheme est respecté
  • Un bouton de bascule est disponible
  • Le bouton a un aria-pressed ou aria-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> :

CODE
<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

  1. RGAA Checker : Scannez votre site dans les deux modes
  2. Chrome DevTools : Rendering > Emulate CSS prefers-color-scheme
  3. 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.

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.