TL;DR
Dark mode is an expected feature on websites and in apps. Implementation relies on system preferences (prefers-color-scheme), CSS variables, and an optional toggle. Done well, it improves UX and reduces eye strain.
Who this is for
- Website and web app owners
- Frontend developers planning dark mode
- Anyone focused on accessibility and user preferences
Keyword (SEO)
dark mode website, dark mode implementation, prefers-color-scheme, dark mode ux
Why dark mode?
- User preference – many users have dark mode enabled in the OS
- Less eye strain – for long reading and evening use
- Consistency with system – the site doesn’t clash with a dark OS UI
- Battery saving – on OLED screens, dark UI uses less power
Step-by-step implementation
1. Detect system preference
@media (prefers-color-scheme: dark) {
:root {
--bg: #1a1a1a;
--text: #e5e5e5;
--accent: #3b82f6;
}
}
2. CSS variables (theme tokens)
:root {
--bg: #ffffff;
--text: #171717;
--accent: #2563eb;
}
[data-theme="dark"] {
--bg: #0f0f0f;
--text: #fafafa;
--accent: #60a5fa;
}
3. Toggle + save in localStorage
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}
// On load: check localStorage, then prefers-color-scheme
const saved = localStorage.getItem('theme');
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
setTheme(saved || (prefersDark ? 'dark' : 'light'));
Best practices
- Not just inverted colors – tune contrast and shades (e.g. avoid pure #000 backgrounds)
- Images and logo – consider variants for dark background or a subtle background behind images
- Keep a toggle – even with prefers-color-scheme, users may want to override
- Test contrast – WCAG still applies (min. 4.5:1 for text)
Checklist
- CSS variables for colors (bg, text, border, accent)
- Support for
prefers-color-scheme - Optional toggle with localStorage persistence
- No flash on first load (script in head or inline critical)
- Test on devices with dark mode enabled
FAQ
Does dark mode affect SEO?
Colors themselves don’t. It can improve UX metrics (time on page, bounce) if users prefer dark theme.
Do I need a toggle?
No. Respecting prefers-color-scheme is enough. A toggle gives users control and is often appreciated.
How to avoid flash on load?
Add a small script in <head> that sets data-theme from localStorage or prefers-color-scheme before first paint, then load the rest.