Dark mode is frequently treated as a simple color inversion exercise, but the well-regarded implementations share a handful of specific, non-obvious details that separate a genuinely comfortable dark mode from one that just technically works.
1Respecting The User's Existing Choice By Default
Most users who prefer dark mode have already told their operating system so, via a system-wide setting. @media (prefers-color-scheme: dark) lets a site respect that existing choice automatically, providing a sensible default without requiring the user to discover and click a separate toggle on every individual site they visit.
The common, well-regarded pattern layers a manual override on top: default to the OS preference via prefers-color-scheme, but also offer an explicit toggle (persisted, typically via localStorage or a cookie) for users who want a site-specific choice different from their system-wide setting — a user might prefer their OS in dark mode generally but want one particular content-heavy reading site in light mode specifically.
2Why #121212 Beats #000000
Pure black against light, high-contrast text creates an unusually extreme contrast ratio. While high contrast is generally good for accessibility, an *excessive* jump — particularly on OLED displays capable of rendering true, deep black — can produce a visually uncomfortable effect for some viewers, sometimes described as text seeming to 'vibrate' or develop a halo, especially in low ambient light where the eye has adapted to darkness.
This is why the overwhelming majority of well-regarded dark mode implementations (major operating systems and popular apps among them) use a dark gray in the #121212-to-#1a1a1a range as their base background instead of literal black — dark enough to unambiguously read as 'dark mode', while meaningfully softer on the eyes over extended viewing.
3Rethinking Elevation Without Effective Shadows
A light-mode design system typically communicates that a card or modal 'floats' above the page background using box-shadow — a dark, soft shadow reads clearly against a light background. That same technique falls apart on a dark background: a dark shadow against an already-dark background has minimal visible contrast, making it an ineffective elevation cue exactly when it's needed most (modals, dropdowns, cards).
The standard solution, borrowed from Material Design and widely adopted since, is an elevation scale expressed through progressively lighter surface fills instead: the base page background is darkest, a card sitting above it gets a slightly lighter fill, and a modal appearing above that card gets lighter still — perceived depth communicated through lightness contrast, which remains clearly visible on a dark background where shadow contrast doesn't.
4Step-by-Step Breakdown
Dark Mode Is More Than Inverted Colors. The Theme Architecture lesson covered the general switching mechanism. Dark mode specifically has its own set of hard-won implementation details — detecting the OS preference correctly, avoiding pure black, and rethinking how elevation and depth are communicated when shadows stop working the way they do on light backgrounds.
Detecting The System Preference With prefers-color-scheme. @media (prefers-color-scheme: dark) reads the OS-level dark mode setting directly, giving a sensible default theme without requiring the user to make an explicit choice — most production dark mode implementations combine this automatic default with a manual override the user can toggle and have remembered.
prefers-color-scheme's Role. What's the typical relationship between prefers-color-scheme and a manual, user-toggleable dark mode switch?
- →A site should only ever use one or the other, never both
- →prefers-color-scheme typically provides the automatic, sensible default, while a manual toggle lets the user explicitly override it if they prefer something different from their OS setting
- →They're unrelated CSS features with no typical interaction
Why Pure Black Is Usually The Wrong Choice. #000000 against white text creates an extremely high contrast ratio that can itself cause eye strain and a distracting 'halation' effect for some users, particularly on OLED screens with true blacks; most well-regarded dark mode implementations use a dark gray (#121212-ish) instead, which still reads as 'dark mode' while being gentler on the eyes.
Avoiding Pure Black. Why do most well-designed dark mode implementations avoid pure black (#000000) as the background color?
- →Because it doesn't actually look dark enough to users
- →Because the extreme contrast against light text can cause eye strain and a distracting halation effect for some users, especially on OLED displays
- →Because pure black isn't technically supported in CSS
Elevation Via Lightness, Not Shadows. On a light background, box-shadow is an effective way to communicate that a card 'floats' above the page. On a dark background, shadows are far less visible (dark shadow on dark background has little contrast), so dark mode design systems typically communicate elevation instead through progressively lighter background shades — a card sitting 'above' the page background gets a slightly lighter fill, and a modal above that card gets lighter still.
Elevation In Dark Mode. Why do dark mode design systems typically communicate elevation through progressively lighter surface colors instead of box-shadow?
- →Because box-shadow doesn't work at all in dark mode
- →Because a dark shadow against an already-dark background has very little visible contrast, making it an ineffective elevation cue
- →Because box-shadow is a performance problem specifically in dark mode
Dark Mode Craft Mastered. You now know the specific, hard-won implementation details that separate a well-executed dark mode from a naive color inversion: reading the OS preference correctly with prefers-color-scheme, avoiding pure black in favor of a gentler dark gray, and communicating elevation through progressively lighter surfaces instead of shadows that lose their contrast on dark backgrounds.
Style A Panel For Dark Mode. A .dark ancestor class scopes an alternate color scheme to everything nested inside it.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1Dark Mode Text Contrast Still Needs Explicit WCAG Verification, Not Assumed Correctness
Simply inverting light-mode colors doesn't guarantee dark-mode contrast ratios meet WCAG AA — the relationship between text and background lightness needs independent verification in the dark theme specifically.
2Avoiding Pure Black Is Itself Partly An Accessibility Consideration, Not Purely Aesthetic
The eye strain and halation effect some users experience with pure black backgrounds against high-contrast text is a genuine visual comfort and accessibility concern, particularly for users with certain visual sensitivities, not merely a stylistic preference.
SEO Implications
- 1
Respecting prefers-color-scheme By Default Improves Perceived Site Quality And Reduces Bounce From Preference Mismatch
Users landing on a site that ignores their clear, already-configured OS preference can perceive it as lower quality or less considered, a soft engagement signal that compounds across a site's user base over time.
- 2
A Well-Implemented Dark Mode Correlates With Reduced Battery Usage On OLED Devices, An Increasingly Weighed UX Factor
True dark pixels on OLED displays use meaningfully less power than light ones, making a genuinely dark (not just gray-on-white-inverted) dark mode a real, measurable benefit for mobile users specifically.
Best Practices
Default To prefers-color-scheme While Still Offering An Explicit, Persisted Manual Override
This respects the user's existing system-wide choice by default while still accommodating the real, common case of wanting a different preference for one specific site.
Build A Dedicated Elevation Token Scale For Dark Mode Rather Than Reusing Light-Mode Shadow Values
Shadows and lightness-based elevation are genuinely different mechanisms; a dark theme needs its own considered elevation scale, not an attempt to force light-mode shadow tokens to work in a context where they're far less effective.
Frequent Bugs
A dark-mode card meant to appear elevated above the page looks visually flat and indistinguishable from the background.
The card is likely still relying on box-shadow for elevation, which has poor contrast on dark backgrounds; switch to a lighter background fill for the elevated surface instead.
Users report eye strain or discomfort specifically when using a site's dark mode for extended periods.
Check whether the background uses pure #000000; switch to a softer dark gray in the #121212 range, which is generally more comfortable while still clearly reading as dark mode.
Real-World Examples
A Complete Elevation Scale For Dark Mode
A dashboard design system defining a four-level elevation scale for dark mode, replacing box-shadow entirely with progressively lighter surface fills for its base, card, dropdown, and modal layers.
--color-bg: #121212;
--color-bg-elevated-1: #1e1e1e; /* cards */
--color-bg-elevated-2: #2a2a2a; /* dropdowns */
--color-bg-elevated-3: #363636; /* modals */