Why Colors Look Duller on Dark (and the 20% Fix)
Here is a thirty-second experiment. Take a brand blue — #2563eb, which is
oklch(0.546 0.215 262.9) — and place two swatches of it side by side: one
on a white card, one on a near-black card. Same hex, same pixels, same
monitor. The swatch on the dark card looks quieter — a little less colorful,
a little tired — even though a color picker will swear the two are
identical. Nothing about the color changed. Only its surroundings did.
Colors look washed out in dark mode because the visual system judges colorfulness relative to the surroundings, not in absolute terms: against a dark ground, the identical chroma value reads noticeably less vivid. The fix is to raise chroma, not lightness — derived dark palettes boost chroma by roughly 20 % so that colors on near-black read as vivid as their light-mode counterparts did on white. This is the perceptual mechanism underneath much of what our dark mode guide covers; this article walks through why it happens, why teams routinely fix the wrong axis, and what the numbers look like.
Why does the same color look less colorful on a dark background?
Because the eye is a relative instrument, not a colorimeter. Two effects from perception research are enough to explain the experiment above, and both are worth knowing in accessible form.
The first is simultaneous contrast — the general finding that a stimulus is perceived relative to what surrounds it, the same family of effects as the contrast effect in perception at large. A patch of color bordered by bright white is being compared, continuously, against something that has no color and maximal light; the same patch bordered by near-black is compared against something that has no color and almost no light. The comparison changes what is perceived, and one of the casualties is colorfulness: against the dark surround, the patch’s color reads as less saturated than it measures.
The second is adaptation. In a dark interface the eye adjusts to a lower overall level of light, and part of how color appearance works is that perceived colorfulness tends to fall as the light level falls — a scene at dusk looks grayer than the same scene at noon, even though the surfaces in it have not changed. A dark theme is a small, self-inflicted dusk.
Neither effect is a display artifact, and neither can be turned off. A dark theme that wants its colors to read the same as the light theme has to compensate for them.
Why do teams fix the wrong axis?
The failure usually announces itself as a vague complaint: the brand color looks tired in dark mode. The instinctive fix is to lighten it — and lightening does make the color pop more, because it increases the luminance contrast between the color and the dark background. That is what makes the instinct so persistent: the adjustment produces a visible improvement on the wrong axis.
But what faded was not lightness — it was colorfulness, and those are different dimensions. Lightening a chromatic color without touching its chroma pushes it toward pastel: the dark-mode blue becomes a paler, milkier blue that no longer matches the brand’s character, and if every accent gets the same treatment the whole dark theme drifts toward candy. The color was never too dark. It was insufficiently colorful for its new surroundings, and the axis that restores it is chroma.
How big should the boost be — and what limits it?
In derived dark palettes, the working figure is a chroma boost of roughly 20 %. The brand blue that runs at C 0.215 on light asks for ≈ C 0.26 on dark to read equally vivid. The qualifier matters: asks for. The boost is a request, and the sRGB gamut has a ceiling at every lightness — some colors sit close enough to it that they cannot take the full 20 %.
Three swatches make the pattern concrete. Each row shows the color as it ships on light, and its boosted dark-mode version:
| Swatch | On light | Boost request | Dark version |
|---|---|---|---|
blue #2563eb | oklch(0.546 0.215 262.9) | ≈0.258 — over the ≈0.25 ceiling | oklch(0.546 ≈0.25 262.9) ≈#125CFE |
green #4A925C | oklch(0.60 0.11 150) | ≈0.132 — clears the ceiling | oklch(0.60 ≈0.132 150) ≈#399654 |
amber #CE9042 | oklch(0.70 0.12 70) | ≈0.144 — just under the ≈0.152 ceiling | oklch(0.70 ≈0.144 70) ≈#D68C1D |
The green and the amber take the full 20 %. The blue cannot: at L 0.546 and hue 262.9°, sRGB runs out of room around C ≈ 0.25, so the boosted blue lands at the ceiling rather than at the request. That is the honest limit of the technique — a seed chosen near the gamut edge has little headroom left for dark mode, which is worth knowing on the day the seed is chosen, not the day the dark theme is built.
Open the two-grounds comparison in Scale Composer — the same three swatches at identical chroma on a white and a near-black surface, so the fading is visible before any fix is applied.

Which colors get the boost?
Not everything, and not uniformly.
Brand and accent ramps: yes. These are the colors whose vividness is the job — buttons, links, highlights, badges. They take the full boost, gamut permitting — one step in the larger work of adapting a brand color for dark mode.
Neutrals: barely, and proportionally. A tinted neutral scale runs at whisper chroma — values like C 0.02 — and the boost scales with the value, so it becomes ≈ 0.024. That is invisible in a swatch and still below what most eyes would call “a color,” which is the point: the boost preserves the neutral’s temperature on the dark ground without turning the stage into a performer.
Functional colors: yes, then re-check. Success greens, warning ambers and error reds fade like everything else and need the boost like everything else — but they also carry contrast obligations, and changing chroma moves a color’s measured contrast slightly. A derived palette re-checks the contrast floors on the dark surfaces after boosting rather than assuming the light theme’s passes carry over; in Scale Composer the dark roles are re-derived with the WCAG floors and APCA checked against the dark surfaces.
See the fix switch on and off
The boost is easiest to evaluate as a before-and-after rather than as a number. Toggle the chroma boost on the dark palette — the same ramps rendered on near-black with the boost off, then on, so you can watch washed-out and equally-vivid trade places on your own screen.