Automatic Dark Mode with prefers-color-scheme 🌗
Dark mode is no longer a “luxury” — it’s a user expectation. YouTube, Twitter, WhatsApp… everyone switched to darker themes at some point. Still writing complex JavaScript theme toggles? You don’t need to anymore! CSS brought its own hero onstage: prefers-color-scheme.
Thanks to this feature, the browser listens to the user’s system setting. If the OS is set to Dark Mode, your website can automatically apply a dark theme. No extra button, no extra JS, no toggleTheme() hassle.
What is prefers-color-scheme?
prefers-color-scheme is a CSS media query. It detects whether the user prefers a light or dark theme at the system level and applies your styles accordingly.
@media (prefers-color-scheme: dark) {
body {
background: #111;
color: #eee;
}
}
That’s it. The browser turns your site dark based on the user’s preference. Likewise:
@media (prefers-color-scheme: light) {
body {
background: #fff;
color: #222;
}
}
…lets you define the light theme too. All that’s left is collecting those “my eyes thank you” comments. 😇
Why is this so good?
- Respects user preference: If the visitor already chose dark mode on their device, you don’t have to ask again.
- Zero JavaScript: The switch happens entirely at the CSS level. Faster render, fewer resources.
- Accessibility gold: Reduces eye strain during nighttime use.
- Auto-sync: If the user changes the OS theme, your site updates instantly.
Adding Manual Control (Optional)
Some users still want to pick their own theme. In that case, a tiny JS touch can override the system preference:
const theme = localStorage.getItem('theme');
if (theme) {
document.documentElement.dataset.theme = theme;
}
And in CSS:
:root[data-theme='dark'] {
background-color: #111;
color: #eee;
}
:root[data-theme='light'] {
background-color: #fff;
color: #222;
}
Now a button can toggle the theme and persist it in the browser. Automatic and manual control together — a democratic dark mode. 😄
Bonus for Designers: Dark Theme ≠ Just a Black Background
Dark mode isn’t only “make the background black.” Light, contrast, and saturation are perceived differently. For example:
- A light gray body text in light theme may nearly disappear on dark backgrounds.
- Colored icons often look less saturated in dark mode.
- Shadows add depth in light themes but can vanish in dark themes.
💡 Pro Tip: Add Transitions
Avoid sudden flashes when switching themes by adding gentle transitions:
html {
transition: background-color 0.3s ease, color 0.3s ease;
}
This makes light ↔ dark transitions smooth. Your users’ eyes will appreciate it.
Browser Support
Modern browsers all support prefers-color-scheme: Chrome, Edge, Firefox, Safari — they recognize the media query.
In very old browsers, CSS fallbacks take over. For example, set a default light theme on body so users never face the “white text on black void” chaos. 🕳️
Extras: Theme-Aware Images
You can swap images based on the system theme as well:
@media (prefers-color-scheme: dark) {
img.logo {
content: url('logo-dark.svg');
}
}
This keeps logos, illustrations, and icons aligned with the environment — no more blinding white logos on dark backgrounds. 🥰
🌚 Conclusion
Dark mode is no longer a “feature” but a standard user expectation. With CSS prefers-color-scheme, you can deliver it easily, performantly, and accessibly.
Instead of wrestling with theme buttons, listen to user preference — CSS decides for you.
Sometimes the best code is the code you never write.