Le mode sombre : pourquoi l’adopter ?
Le mode sombre (dark mode) réduit la fatigue oculaire, économise la batterie sur les écrans OLED, et la plupart des utilisateurs le préfèrent. Voici comment l’implémenter proprement avec CSS et JavaScript.
Étape 1 : Les variables CSS (la base)
Définissez vos couleurs comme variables CSS pour pouvoir les changer facilement :
:root {
/* Mode clair (par défaut) */
--bg-primary: #ffffff;
--bg-secondary: #f5f5f5;
--text-primary: #1a1a1a;
--text-secondary: #666666;
--accent: #667eea;
--border: #e0e0e0;
--card-bg: #ffffff;
--card-shadow: rgba(0, 0, 0, 0.1);
}
/* Mode sombre */
[data-thème="dark"] {
--bg-primary: #1a1a2e;
--bg-secondary: #16213e;
--text-primary: #e0e0e0;
--text-secondary: #a0a0a0;
--accent: #818cf8;
--border: #2d3748;
--card-bg: #1e293b;
--card-shadow: rgba(0, 0, 0, 0.4);
}
Étape 2 : Appliquer les variables dans le CSS
body {
background-color: var(--bg-primary);
color: var(--text-primary);
transition: background-color 0.3s ease, color 0.3s ease;
}
.card {
background: var(--card-bg);
border: 1px solid var(--border);
box-shadow: 0 2px 10px var(--card-shadow);
border-radius: 12px;
padding: 20px;
transition: all 0.3s ease;
}
header {
background: var(--bg-secondary);
border-bottom: 1px solid var(--border);
}
a { color: var(--accent); }
h1, h2, h3 { color: var(--text-primary); }
p { color: var(--text-secondary); }
Étape 3 : Le bouton de bascule
<!-- HTML du toggle -->
<button id="thème-toggle" aria-label="Changer de thème">
<span class="icon-soleil">☀️</span>
<span class="icon-lune">🌙</span>
</button>
<style>
#thème-toggle {
background: var(--bg-secondary);
border: 2px solid var(--border);
border-radius: 30px;
padding: 8px 16px;
cursor: pointer;
font-size: 20px;
transition: all 0.3s;
}
/* Cacher l'icône inactive */
[data-thème="dark"] .icon-soleil { display: inline; }
[data-thème="dark"] .icon-lune { display: none; }
:root .icon-soleil { display: none; }
:root .icon-lune { display: inline; }
</style>
Étape 4 : Le JavaScript (avec sauvegarde du choix)
const toggle = document.getElementById('thème-toggle');
// Vérifier la préférence sauvegardée ou système
function getThemePreference() {
const saved = localStorage.getItem('thème');
if (saved) return saved;
// Détecter la préférence du système
return window.matchMedia('(prefers-color-scheme: dark)').matches
? 'dark' : 'light';
}
// Appliquer le thème
function setTheme(thème) {
document.documentElement.setAttribute('data-thème', thème);
localStorage.setItem('thème', thème);
}
// Initialiser au chargement
setTheme(getThemePreference());
// Basculer au clic
toggle.addEventListener('click', () => {
const current = document.documentElement.getAttribute('data-thème');
const newTheme = current === 'dark' ? 'light' : 'dark';
setTheme(newTheme);
});
// Écouter les changements de préférence système
window.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (e) => {
if (!localStorage.getItem('thème')) {
setTheme(e.matches ? 'dark' : 'light');
}
});
💡 Astuce : éviter le flash blanc
Placez ce script dans le <head> (avant le CSS) pour appliquer le thème avant l’affichage :
<script>
const t = localStorage.getItem('thème') ||
(matchMedia('(prefers-color-scheme:dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-thème', t);
</script>
Gérer les images en mode sombre
/* Réduire la luminosité des images en mode sombre */
[data-thème="dark"] img {
filter: brightness(0.85);
transition: filter 0.3s;
}
/* Image spécifique pour le mode sombre */
<picture>
<source srcset="logo-dark.png" media="(prefers-color-scheme: dark)">
<img src="logo-light.png" alt="Logo">
</picture>
/* Ou avec CSS */
.logo-light { display: block; }
.logo-dark { display: none; }
[data-thème="dark"] .logo-light { display: none; }
[data-thème="dark"] .logo-dark { display: block; }
Toggle animé (switch iOS style)
<label class="switch">
<input type="checkbox" id="dark-toggle">
<span class="slider"></span>
</label>
<style>
.switch {
position: relative;
width: 56px;
height: 28px;
}
.switch input { display: none; }
.slider {
position: absolute;
inset: 0;
background: #ccc;
border-radius: 28px;
cursor: pointer;
transition: 0.3s;
}
.slider::before {
content: "☀️";
position: absolute;
height: 22px;
width: 22px;
left: 3px;
bottom: 3px;
background: white;
border-radius: 50%;
transition: 0.3s;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
input:checked + .slider { background: #667eea; }
input:checked + .slider::before {
transform: translateX(28px);
content: "🌙";
}
</style>
Exercice pratique
🎯 Défi : Mode sombre complet
- Créez une page avec header, cards et footer
- Définissez les variables CSS pour les 2 thèmes
- Ajoutez un toggle animé type switch
- Sauvegardez le choix dans
localStorage - Détectez la préférence système avec
prefers-color-scheme - Bonus : ajoutez un 3ème mode « auto » qui suit le système