Designing Dark Mode: Beyond Inverting Your Colors
Designing a good dark mode is not a 5-minute job of swapping `#fff` for `#000`. Done badly, dark mode causes eye strain, breaks brand identity, and fails contrast in surprising places. Done well, it reduces fatigue, saves OLED battery, and looks premium.
This article covers the five design decisions that separate "inverted" dark mode from "designed" dark mode.
1. Avoid pure black
Pure black (#000000) on a glowing screen produces "halation" - bright text bleeds into the surrounding dark, blurring edges. Use a near-black like `#0a0a0f` or `#101015` instead.
Material Design recommends `#121212` as the elevation 0 surface. iOS uses `#1c1c1e`. Both feel dark without the OLED-blur problem.
2. Lower the chroma of your brand color
A brand color tuned for white backgrounds is usually too saturated for a dark surface. The same red that pops cleanly on `#fff` looks neon and aggressive on `#0a0a0f`.
In OKLCH, drop chroma by 30-50% for dark mode while keeping the same hue. The color stays on-brand but stops vibrating.
3. Use elevation, not just color
In light mode, elevation = shadow. In dark mode, shadows do not show, so elevation = lighter surface. Build a 4-5 step surface scale: `#0a0a0f`, `#15151b`, `#1f1f26`, `#2a2a32`. Each "raised" element uses the next lighter step.
This is how iOS, Material Design, and most modern dashboards convey card / modal / popover hierarchy in dark mode.
4. Re-test every contrast pair
Dark-mode contrast does not mirror light-mode contrast. A pair that scored 7.2:1 in light mode might land at 4.1:1 in dark mode. Run every text-on-surface combination through the contrast checker and adjust.
APCA is particularly useful here because it correctly identifies where dark-mode text genuinely fails, while WCAG 2.1 sometimes over-rates dark combinations.
5. Provide a way to opt out
Some users (older eyes, certain visual conditions) read better in light mode regardless of system preference. Always offer a manual toggle and persist the choice. Do not assume `prefers-color-scheme: dark` is correct for everyone.
/* Tokens that adapt automatically */
:root { --surface: #fff; --text: #1a1a1a; }
[data-theme="dark"] { --surface: #0f1015; --text: #e5e5e7; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) { --surface: #0f1015; --text: #e5e5e7; }
}Try the related tools
Frequently asked questions
Should dark mode invert my brand color?
No - keep the hue, lower the chroma 30-50% and adjust lightness to maintain contrast. Inverting changes the hue and breaks brand recognition.
Does dark mode save battery?
On OLED screens (most modern phones, some laptops), yes - black pixels are off. On LCD screens, no - the backlight is on regardless of pixel content.
How dark should the darkest surface be?
Around `#0a0a0f` to `#15151b`. Pure black causes halation; mid-grays fail contrast. Aim for an L value of 0.08-0.12 in OKLCH.