The common approach to dark mode is to take the light palette, flip the greys, and fix what looks wrong. It usually ships, and it usually has the same set of problems: elevation that reads as flat, brand colours that vibrate against dark backgrounds, disabled states indistinguishable from enabled ones, and shadows that do nothing because shadow on dark is nearly invisible.
Design roles, not colours
The fix is to stop thinking in colours and start thinking in roles: page background, raised surface, overlay surface, primary text, secondary text, border, interactive accent, and the state variants of each. A role has a meaning that holds in both themes, and each theme provides its own value. Once your components reference roles, a theme is a value table rather than a set of overrides.
The tell that a system is not doing this is a stylesheet full of theme-specific exceptions, each one added to patch a place where inversion produced a bad result.
Elevation without shadows
On light backgrounds, depth is communicated by shadow. On dark backgrounds shadow barely registers, so depth has to come from surface lightness: each level up is slightly lighter than the one below. Define these steps explicitly, keep them few, and resist the temptation to also add a shadow, which usually reads as a smudge.
Saturated colours need adjusting
A brand colour tuned for white backgrounds will typically be too saturated and too dark against a dark surface. It either disappears or glows uncomfortably. Most systems end up with a slightly desaturated, slightly lighter variant for dark mode, defined once as a role value rather than adjusted per component.
- Pure white text on pure black is harsh; a near-white on a near-black is more comfortable for long reading.
- Contrast requirements apply in both themes, and a pairing that passes in light frequently fails in dark.
- Images and illustrations need consideration too, since a white-background asset becomes a bright rectangle.
Respect all three states
Users have three preferences, not two: light, dark, and follow the system. Products that only store an explicit choice break for the largest group, who never chose and expect the operating system to decide. Handle the unset state as first-class, and make sure the toggle can return to it.
If your dark theme was made by inverting the light one, your users can tell. It is the interface equivalent of a translated sentence that is technically correct.
The test that finds everything
Put both themes side by side on the same screen and look at states rather than layouts: hover, focus, disabled, error, selected, and loading. Theme bugs concentrate almost entirely in states, because states are where colour is doing semantic work rather than decorative work.
Join the conversation
Discussion0
Join the conversation. Sign in to leave a response or reply to comments.