Cansu Arı Logo
Blog
What is it?

The Most Modern Dark Mode Approach in Frontend: CSS prefers-color-scheme

Dark themes that delight users: automatic dark mode with CSS’s new hero, prefers-color-scheme!

  • #CSS
  • #Accessibility

Skip to content

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.
In short, when the user says “I want dark mode,” CSS hears it and acts. A kind of frontend telepathy.

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.
So dark theme design requires reevaluating contrast and readability. Even typographic weights may change — e.g., “Medium” can read clearer than “Regular” on dark backgrounds.

💡 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.

All tags
  • CSS
  • Accessibility