Design & UI/UX CSS Dark Mode JavaScript

Dark mode : implémenter le mode sombre en CSS et JS

Implémentez le dark mode sur votre site : CSS custom properties, prefers-color-scheme, localStorage et toggle JS. Guide complet avec exemples.

Benjamin Schweitzer Benjamin Schweitzer
Mardi 15 avril 2025
4 min de lecture
Dark mode : implémenter le mode sombre en CSS et JS

Le dark mode est devenu une attente standard des utilisateurs depuis son adoption par iOS et Android. Implémenter un dark mode de qualité améliore l'expérience utilisateur, réduit la fatigue oculaire en faible luminosité et peut prolonger l'autonomie des appareils OLED. Voici comment le faire correctement.

Stratégie recommandée : CSS Custom Properties

La solution la plus maintenable utilise des variables CSS (custom properties) pour définir un système de design theméable :

:root {
  --bg: #ffffff;
  --bg-card: #f8fafc;
  --text: #0f172a;
  --text-muted: #64748b;
  --border: #e2e8f0;
  --primary: #2E5693;
}

[data-theme="dark"] {
  --bg: #0f172a;
  --bg-card: #1e293b;
  --text: #f1f5f9;
  --text-muted: #94a3b8;
  --border: #334155;
  --primary: #60a5fa;
}

body { background: var(--bg); color: var(--text); }
.card { background: var(--bg-card); border: 1px solid var(--border); }

Il suffit de changer l'attribut data-theme sur le pour basculer tout le thème instantanément.

Détection automatique avec prefers-color-scheme

Le media query prefers-color-scheme respecte la préférence système de l'utilisateur :

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f172a;
    --text: #f1f5f9;
    /* ... */
  }
}

Cette approche respecte automatiquement les préférences sans JavaScript. Mais elle ne permet pas à l'utilisateur de choisir indépendamment de son système.

Toggle JavaScript avec persistance

La solution complète : détection automatique + toggle manuel + mémorisation :

const toggle = document.getElementById('themeToggle');
const html = document.documentElement;

// Priorité : préférence sauvegardée > préférence système
function getTheme() {
  return localStorage.getItem('theme') ||
    (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
}

function applyTheme(theme) {
  html.setAttribute('data-theme', theme);
  localStorage.setItem('theme', theme);
  toggle.setAttribute('aria-label', theme === 'dark' ? 'Mode clair' : 'Mode sombre');
}

// Application immédiate (avant le rendu) pour éviter le flash
applyTheme(getTheme());

toggle.addEventListener('click', () => {
  applyTheme(html.getAttribute('data-theme') === 'dark' ? 'light' : 'dark');
});

Éviter le flash au chargement (FOUC)

Sans précaution, la page s'affiche brièvement en mode clair avant d'appliquer le dark mode. La solution : exécuter le script de thème dans le , avant tout CSS :

<head>
  <script>
    (function() {
      var theme = localStorage.getItem('theme') ||
        (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
      document.documentElement.setAttribute('data-theme', theme);
    })();
  </script>
  <link rel="stylesheet" href="style.css">
</head>

Images et dark mode

Certaines images (logos, illustrations) doivent s'adapter au dark mode. Deux approches :

[data-theme="dark"] img.logo { filter: invert(1) hue-rotate(180deg); }

Ou utiliser le tag avec prefers-color-scheme :

<picture>
  <source srcset="logo-dark.svg" media="(prefers-color-scheme: dark)">
  <img src="logo-light.svg" alt="Logo">
</picture>

Accessibilité du dark mode

Assurez des ratios de contraste suffisants dans les deux modes (WCAG AA : 4.5:1). Évitez le blanc pur (#fff) sur fond noir pur (#000) : trop de contraste fatigue aussi les yeux. Préférez #f1f5f9 sur #0f172a. Le Contrast Checker de WebAIM vérifie vos combinaisons de couleurs.

Conclusion

Un dark mode bien implémenté avec des variables CSS et un toggle JavaScript avec persistance prend quelques heures mais apporte une valeur réelle aux utilisateurs. Commencez par définir votre palette de couleurs en variables CSS, puis ajoutez les variantes sombres et le toggle. Le résultat professionnel en vaut largement l'investissement.

Le dark mode est désormais une attente utilisateur standard. Pour une implémentation vraiment robuste, combinez prefers-color-scheme pour la détection automatique, localStorage pour mémoriser le choix utilisateur, et des CSS custom properties pour zéro duplication de code. N'oubliez pas les images : utilisez picture avec source media="(prefers-color-scheme: dark)" pour servir des variantes sombres. Testez avec Polypane qui simule les deux modes simultanément. Le plus grand écueil reste les couleurs sur fond sombre : visez un ratio de contraste WCAG AA minimum de 4.5:1 dans les deux modes pour garantir l'accessibilité à tous les utilisateurs.

Dark mode et accessibilité

Un dark mode bien conçu améliore l'accessibilité pour les utilisateurs photosensibles et réduit la fatigue oculaire dans les environnements sombres. Vérifiez que vos couleurs en dark mode respectent les critères WCAG 2.1 AA (ratio 4.5:1 pour le texte normal, 3:1 pour le texte large) avec des outils comme la Color Contrast Analyzer. Testez également avec des utilisateurs ayant des déficiences visuelles pour valider les choix de couleurs dans les deux modes.

Cet article vous a plu ?

Donnez-lui une note, ça m'aide vraiment !

Partager l'article