Home · Blog · Dark mode colour

Colour for dark mode: it's not just inverted

26 Sep 2026 · Colour · 7 min read

The naive approach to dark mode is seductive: take the light palette, flip it, ship it. White becomes black, black becomes white, and everything in between gets mirrored. It takes an afternoon, it looks impressively different in the demo, and it is wrong in ways that only become obvious after a week of real use — washed-out accents, glowing text, buttons that look disabled, and a whole interface that feels somehow cheaper than its light sibling.

The reason is that colour is contextual. The same hex value looks and behaves differently on a dark background than on a light one, because human vision adapts to the overall light level and judges everything relative to it. Designing for dark mode means re-tuning the palette for a different visual environment, not running the old one through a mirror. This article explains what changes, why, and gives a practical method for adapting any palette properly.

Why the same colour looks different on dark

Three perceptual effects do most of the damage. First, saturation blooms: a colour that looks pleasantly vivid on white looks noticeably more intense on black, because there's no bright surround competing with it. The brand blue that was confident on a light page becomes electric — almost neon — on a dark one. This is why dark themes almost always desaturate their accents: the background is doing part of the vividness work for free.

Second, light text glows. Pure white text on a black background appears bolder and slightly blurred compared to black text on white, an effect called halation — light scatters a little inside the eye, and bright-on-dark maximises it. The result is text that feels heavier than its font weight and tiring over long passages. The universal fix is to stop using pure white: text at #E8EAF0 or similar high-but-not-maximum lightness keeps full legibility while killing the glow. Similarly, pure black backgrounds are rarely ideal; near-blacks like #0B0E14 or #121212 reduce the harshness and give shadows and elevation somewhere to go.

Third, contrast perception shifts. A pair that scored 7:1 on light might feel harsher than necessary on dark, while a subtle border that was visible on white can vanish on black. The WCAG ratios still apply — the math doesn't change — but the experience of a given ratio changes with the surround. Dark themes routinely need their "subtle" elements (borders, dividers, placeholder text) lightened beyond what the light theme used, because dark-on-dark differentiation is perceptually harder than the equivalent light-on-light step.

The elevation problem

Here's a structural issue inversion can't solve. Light interfaces communicate depth with shadows: cards float above the page on soft grey blurs. On a dark background, shadows are nearly invisible — you can't darken what's already near-black. So dark themes invert the elevation language: instead of darker shadows, surfaces get lighter as they rise. A card sitting above the background is a few lightness steps brighter than the base; a modal above the card is brighter still.

This "elevation as lightness" system needs its own palette thinking. You need a ramp of surface colours — base, raised, overlay — each clearly separated but harmonious, typically 4–8% lightness apart. And because the surfaces are doing the structural work that shadows did, your accent and text colours must be verified against every surface level, not just the base background. A text colour that passes on the base but fails on the raised card is a bug your light theme never had, because its surfaces were all the same white.

A practical adaptation method

Rather than inverting, rebuild the palette role by role. Here's a method that works:

  1. Set the base first. Pick a near-black with a hint of your brand's hue temperature — a barely-blue #0B0E14 feels designed where pure #000000 feels default. Avoid going below ~4% lightness; true black crushes subtle distinctions and maximises halation.
  2. Build the surface ramp. Create 3–4 surface steps above the base (e.g. 7%, 11%, 16% lightness), keeping the same hue whisper. These are your cards, menus and dialogs.
  3. Remap text colours. Body text lands around 85–92% lightness (never 100%). Secondary text around 60–70%. Disabled/hint text around 40–50% — and verify each against every surface it can sit on.
  4. Desaturate and lighten accents. Take each brand accent and reduce saturation by roughly 10–20 points while raising lightness slightly. A hsl(172, 66%, 50%) teal might become hsl(172, 50%, 62%) for dark mode — calmer, and actually more legible against the dark base.
  5. Re-verify every pair. Contrast ratios, but also the subjective checks: does anything glow, vibrate or disappear? Squint at the design — the squint test is brutally effective on dark themes.
  6. Handle imagery. Photos and illustrations made for light contexts can look like holes punched in a dark page. Slightly dimming images in dark mode (a brightness(0.9) filter) or adding subtle borders so they sit intentionally on the surface goes a long way.
ElementLight theme habitDark theme adjustment
BackgroundPure white #FFFFFFNear-black #0B0E14–#121212
Body textNear-blackHigh grey #E8EAF0, never pure white
AccentsFull saturationDesaturate 10–20 pts, lighten slightly
ElevationShadowsLighter surfaces per level
Borders/dividersSubtle dark linesLighter than you'd expect; dark-on-dark needs more
ShadowsSoft and visibleBarely visible; use sparingly or not at all

What inversion gets wrong, specifically

It's worth naming the failure modes of the flip-it approach, because they're so consistent they form a checklist of what to look for in any dark theme: brand colours that turned neon; text with a visible halo; disabled states indistinguishable from active ones (because "greyed out" was designed as darker-on-light and became lighter-on-dark, reading as emphasised); warning reds that now scream; success greens that now glow like dashboard lights; and depth cues that vanished entirely because the shadows have nothing to darken. If your dark mode has more than two of these, it was inverted, not designed.

A quick self-test for any dark palette

Before shipping, run the palette through five minutes of hostile conditions. Turn your screen brightness to minimum and check that secondary text and borders are still distinguishable — dark themes die first in low brightness. Take the design into bright daylight and confirm nothing critical relied on subtle dark-on-dark differences. Blur your vision slightly (or squint hard) and verify the page's hierarchy survives: headlines, primary actions and section boundaries should still read clearly when fine detail is gone. Finally, toggle between light and dark rapidly a few times; any element that seems to jump, flash or change meaning between modes is a sign the two palettes weren't designed as siblings. These are crude tests, but they catch the failures that contrast ratios miss, because they test perception rather than arithmetic.

The honest caveats

Two things to keep in perspective. First, dark mode is not universally better — for long-form reading in bright environments, dark text on light still wins on legibility and reduced eye strain for most people, and some users with astigmatism actually read worse with light text on dark (halation hits them harder). Offer dark mode as a choice, respect the operating system's preference as the default, and never assume it's the superior option for everyone.

Second, maintaining two tuned palettes is real ongoing work. Every new colour added to the system needs its dark-mode counterpart designed, not derived — which is why design tokens (named roles like surface-raised and text-primary, each with light and dark values) beat raw hex values scattered through a codebase. The token is the contract; the two palettes are its implementations. Set that up once and dark mode stops being a project and becomes a property of the system.

Try the Colour Studio