Colour Love

Dark mode isn't just black

Good dark themes are not built on #000000. They are built on a ladder of warm near-blacks, a contrast budget, and a careful restraint on pure saturation. Here is the ladder.

Most design-system attempts at dark mode look bad for the same reason. The designer flips the existing light theme, background becomes black, text becomes white, accent colours stay the same, and assumes the job is done. Then users report eye strain, readability complaints, and one specific error message nobody can read because it is pure red on pure black and the vibration between the two is unbearable.

Good dark themes are engineered. They are not inversions. Here is what is actually going on and how to build one that holds up.

Pure black is not the right background

#000000 is only the right background if your display is OLED or MicroLED and you are optimizing for battery savings. On LCD panels, still the majority of screens in 2026, pure black is not actually black. The backlight is always on. #000000 shows up as a slightly-illuminated dark grey, and pure white text on that grey produces the harshest contrast a screen can emit.

This harshness is the single biggest cause of dark-mode eye strain. The human visual system evolved to see light reflected off surfaces, not emitted from them. Maximum-emission pure white on minimum-emission pure black triggers the same fatigue as staring at a bare lightbulb in a dark room.

Good dark themes use a slightly raised black as the base, something in the range of #0B0B0D to #18181B. Dark enough to feel like dark mode. Not so dark that white text becomes a strobe.

The warm/cool tilt matters

A neutral dark grey is mathematically clean but visually unpleasant. Designers have known for decades that pure neutral greys look “clinical” or “plasticky” on screen. Dark themes work better when the background has a slight warm or cool tilt.

Apple’s macOS dark mode tilts cool, with a slight blue undertone. Windows 11 tilts cool too. iOS dark mode tilts almost-neutral but with a hair of blue. Slack and Discord tilt neutral-to-warm.

Why does this help? The human eye is more sensitive to blue in low-light conditions. A cool-tilted background appears “darker” to the eye than a warm-tilted one at the same measured lightness. This matters because it lets you push the background lightness up slightly, giving the user a softer contrast, while still feeling like dark mode.

For most product contexts, tilt slightly cool. Apps that want to feel cozy (reading apps, wellness apps) sometimes tilt slightly warm. Either is fine. Pure neutral grey is the choice that almost always feels wrong.

The ladder

A well-built dark theme is a ladder of background shades, each roughly 2–4% lighter than the last. These are used to communicate depth, cards sit on top of backgrounds, modals on top of cards, popovers on top of modals. Each layer needs its own shade.

A typical ladder for a cool-tilted dark theme might look like:

  • Background base, #0B0B0F, the darkest. Main canvas.
  • Surface 1, #15151B, for cards and inline panels.
  • Surface 2, #1F1F27, for modals, popovers, floating elements.
  • Surface 3, #2A2A33, for nested modals or highest-elevation menus.
  • Hairline, #33333D, for border lines and dividers.

Use OKLCH to author these. A ladder in OKLCH is simply a scale of increasing L values at constant C and H. In hex, the same ladder is a set of magic numbers.

Dark-mode ladder (cool tilt) Each step is roughly 2–4% lighter than the one below. #0B0B0F · Base canvas #15151B · Surface 1 · Cards #1F1F27 · Surface 2 · Modals, popovers #2A2A33 · Surface 3 · Nested elements #33333D · Hairline · Dividers and borders
The skeleton of a good dark theme. Elevation maps to lightness.

This ladder is the skeleton of a good dark theme. Everything else, text, accents, interactive states, sits on top of it.

Text contrast, the 4.5:1 rule and its complications

WCAG 2.1 AA requires a contrast ratio of at least 4.5:1 between text and its background for body text, and 3:1 for large text. This is a minimum, not a target.

On a background of #15151B, these hex values produce the following contrast ratios:

  • #FFFFFF (pure white), 17.6:1. Comfortably passes. Often too harsh for body text.
  • #E5E5EA (near-white), 14.9:1. Still comfortable. Feels softer, easier to read at length.
  • #A1A1AA (mid grey), 7.3:1. Passes AAA. Good for secondary text.
  • #71717A (darker grey), 4.6:1. Just passes AA. Use for tertiary text, captions.
  • #52525B (dark grey), 3.1:1. Fails AA for body, passes for large text.

Build your text scale at the AAA level (7:1) when possible. The difference between “passes the contrast checker” and “comfortable to read for an hour” is substantial, and most dark themes skew too faint.

Saturation is the silent killer

Here is the trap nobody warns you about. Take a well-designed light-mode accent colour, say, #3366FF, a bright saturated blue. Drop it into dark mode against a #15151B background. It vibrates. The eye cannot settle on the edges. After a few seconds it becomes actively painful.

The problem is not the contrast. The contrast ratio is fine. The problem is that highly saturated colours become overwhelming against dark backgrounds, because the eye has nothing to anchor against. Saturation that reads as “energetic” in light mode reads as “hostile” in dark mode.

The fix is to desaturate and lighten accent colours for dark-mode use. #3366FF becomes something like #6B8EFF, a softer, lighter, less-saturated version of the same hue. The brand colour is still recognizable. The eye strain is gone.

Every mature dark-mode design system has this adjustment built in. Material Design, Apple’s Human Interface Guidelines, Tailwind’s slate/neutral scales, all of them desaturate accents for dark mode.

The “pitch black OLED” variant

One genuine exception to everything above is a pitch-black OLED variant designed specifically for battery savings on OLED phones. On OLED, a truly black pixel is off, consuming no power. A dark theme at #000000 can extend phone battery life by 10–30% compared to a #111111 theme, depending on screen-on time and content mix.

If you ship a mobile app, consider offering a “pitch black” or “AMOLED” variant in addition to your normal dark theme. Build it by taking the normal dark theme and snapping all surfaces to #000000, while keeping the text and accent adjustments from the normal dark theme. Slack, Twitter, and many others offer this.

Do not make it the default. It is uncomfortable on LCD and unnecessary on desktop.

Dark mode is a separate design, not an inversion

The most important thing to internalize is that dark mode is not a CSS filter on your light theme. It is a parallel design system that shares your brand, your type, and your layout, but has its own colour language. Treat it as such. Build the ladder. Build the text scale. Re-tune the accents. Test on LCD and OLED. Proof on a real device, not a simulator.

This is more work than one prefers-color-scheme media query. It is also the difference between a dark mode that people enable and use, and a dark mode that appears as a checkbox in the settings and gets ignored.

If you want to see what this looks like done well, look at the macOS system UI, Linear, or Stripe’s dashboard. If you want to see it done poorly, look at the majority of indie apps that inverted their light theme and shipped. Your eyes already know the difference.

One more thing

Test dark mode with real content, in a real dark room, at 11pm. The subtle problems only show up at the edges of fatigue. A theme that looks perfect in the office at noon is not a theme that has been tested.

Frequently asked questions

Why shouldn't dark mode backgrounds be pure #000000?
On LCD panels the backlight stays on, so pure black is really illuminated dark grey. Pure white text on that surface creates the harshest possible contrast and causes eye strain. Use a slightly raised black like #0B0B0F to #18181B instead.
What is a dark-mode ladder?
A staged scale of background shades, each 2–4% lighter than the one below it. Used to communicate depth: base canvas, cards, modals, popovers, nested elements. Each layer gets its own shade.
Should I warm-tilt or cool-tilt my dark theme?
Slightly cool for most products. Warm for cozy or reading apps. Neutral grey almost always feels clinical. The human eye is more sensitive to blue in low light, so cool backgrounds can feel darker at the same measured lightness.
Why do saturated accent colours look wrong in dark mode?
Highly saturated colours against dark backgrounds vibrate, the eye cannot settle on the edges. Desaturate and lighten accents for dark mode. The brand recognisability survives; the eye strain disappears.
When does pure black make sense?
On OLED or AMOLED phone screens, where black pixels are physically off and save battery. Offer a separate pitch-black variant for those users; do not make it the default.
Is dark mode just inverting colours?
No. A good dark theme is a parallel design system, same brand and type, different colour language. Inversion produces harsh whites, broken gradients, and painful accent colours.

Defined terms

Ladder
A staged scale of background shades in a dark theme. Each step (base, surface 1, surface 2, etc.) is slightly lighter, communicating depth and hierarchy.
OLED
Organic Light Emitting Diode. A display technology where each pixel emits its own light. Black pixels are truly off, so dark UIs save battery.
Raised black
A near-black background (e.g. #0B0B0F) used instead of pure #000000 to reduce the harsh contrast of emissive screens on LCD panels.
Desaturation
Reducing the chroma of a colour. For dark mode, saturated accents are desaturated and lightened so they don't vibrate against the dark background.
AMOLED
Active-Matrix OLED. A common phone display tech. Black pixels draw no power, so a black-background theme can extend battery life by 10–30%.
Elevation
The visual rank of a surface, higher-elevation surfaces (modals, popovers) sit above lower ones (cards, canvas). Expressed in dark mode via lighter shades on the ladder.

More articles