Dark Mode Guide
CSS Custom Properties Approach
/* Step 1: Define light mode defaults */ :root { --bg: #ffffff; --surface: #f4f4f8; --text: #1a1a2e; --text-muted: #6b7280; --border: #e5e7eb; } /* Step 2: Override for system dark mode */ @media (prefers-color-scheme: dark) { :root { --bg: #0f1117; --surface: #1c2035; --text: #e2e8f0; --text-muted: #8b92a5; --border: #2a2f4a; } } /* Step 3: Class-based toggle override */ [data-theme="dark"] { --bg: #0f1117; --surface: #1c2035; } [data-theme="light"] { --bg: #ffffff; --surface: #f4f4f8; }
JavaScript Toggle with localStorage
// Prevent flash of wrong theme (add to <head>) (function() { const saved = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; document.documentElement.dataset.theme = saved || (prefersDark ? 'dark' : 'light'); })(); // Toggle button logic function toggleTheme() { const current = document.documentElement.dataset.theme; const next = current === 'dark' ? 'light' : 'dark'; document.documentElement.dataset.theme = next; localStorage.setItem('theme', next); }
Dark Mode Best Practices
| Rule | Reason |
|---|---|
| Use #1c2035 not pure #000000 for backgrounds | Pure black causes too much contrast |
| Reduce saturation of colors in dark mode | Vibrant colors glow uncomfortably on dark |
| Invert images selectively (icons, diagrams) | Photos look wrong when fully inverted |
| Add transition: color 0.2s ease for smooth switch | Avoids jarring instant change |
| Test with users who have light sensitivity | Accessibility is the primary use case |