The Helmholtz-Kohlrausch Effect: Why Saturated Colors Look Brighter
Why do saturated colors appear brighter than gray at the same luminance? The science of the H-K effect and how Helmlab models it.
You are designing an interface. You place a saturated red badge on a gray background. You set both to the same lightness value -- identical L coordinates. But your eyes tell a different story: the red badge clearly looks brighter. Your eyes are not wrong. This is one of color science's oldest and most important phenomena: the Helmholtz-Kohlrausch effect.
In this post, we explore the science behind this effect, why modern color spaces ignore it, and how Helmlab embeds it directly into its pipeline.
The Discovery: Helmholtz and Kohlrausch
The effect is named after two German scientists. Hermann von Helmholtz (1821--1894) was one of the first to systematically study the physiology of human vision. His monumental Handbuch der physiologischen Optik remains a foundational text in color science. Friedrich Kohlrausch (1840--1910) was a physicist and engineer known for precise experimental methods in optical measurement.
What they discovered was simple but profound: as a color's saturation increases, it is perceived as brighter even at the same luminance. In other words, chromaticity alone creates a sensation of additional brightness.
This effect has been known since the 19th century. Yet the vast majority of modern color spaces still do not model it, which means designers and developers fall into this trap every day.
See It Yourself: Gray vs Saturated Red
The two circles below have the same CIE luminance value. The left one is a neutral gray, the right one is a saturated red. Which one looks brighter?
Most people will perceive the red circle as brighter. This is not an optical illusion -- it is a physiological property of your visual system. The cone cells in your retina are stimulated at different levels across wavelengths, and this aggregate stimulation produces a brightness signal that goes beyond pure luminance. A chromatic stimulus creates more neural "activation" at the aggregate level.
Why It Matters: Everyday Design Decisions
This effect is not an academic curiosity -- it directly affects design decisions you make every day:
- Buttons -- A "Confirm" button in saturated green and a "Cancel" button in neutral gray. Even at the same L value, the green button appears to stand out more, disrupting your intended visual hierarchy.
- Badges and labels -- A saturated red "Urgent" badge next to a gray badge at the same lightness will look brighter. This might be intentional, but if it is happening without your awareness, it creates problems.
- Text readability -- White text on a saturated background may result in lower contrast than expected, because the saturated background "looks brighter than it should."
- Color scales -- In a 50-to-950 palette, high-chroma steps perceptually "drift" in lightness, making supposedly equal steps visually unequal.
- Dark mode -- On dark backgrounds, the H-K effect becomes more pronounced. Saturated accent colors pop out far more than expected.
Why Lab, Oklab, and CIEDE2000 Ignore This
Three major standards dominate color science: CIE Lab (1976), CIEDE2000 (2001), and Oklab (2020). All three share a common blind spot: they do not model the Helmholtz-Kohlrausch effect.
CIE Lab
CIE Lab calculates L* using only the Y (luminance) channel: L* = 116 * (Y/Yn)^(1/3) - 16. The chromaticity values (a*, b*) play no role in the L* calculation. If two colors have the same Y value, they get the same L* -- regardless of how saturated they are.
Oklab
Oklab uses a more modern approach: an XYZ-to-LMS matrix transform followed by cube roots. But with only 18 parameters total, its L axis is still computed independently of chromaticity. A saturated blue and a gray at the same luminance receive the same Oklab L value.
CIEDE2000
CIEDE2000 is a distance formula, not a color space, so it does not directly compute lightness. It applies weighted corrections on top of CIE Lab. But since it fundamentally relies on CIE Lab's L* value, it inherits the H-K blind spot.
All three standards ignore this effect for a historical reason: simplicity. CIE Lab was designed in 1976 as a "good enough" practical solution. Oklab aimed to be a minimalist 18-parameter model. Modeling the H-K effect requires additional parameters, additional complexity, and additional care to ensure invertibility at every stage. These spaces chose simplicity -- but that choice has a cost.
How Helmlab Solves This: H-K Embedded in the L Axis
Helmlab uses a 13-stage pipeline. At stage 3.7, immediately after hue correction and immediately before cubic L correction, it applies a chroma-dependent lightness shift:
// Stage 3.7 of the Helmlab pipeline
// L += hk_weight * C^hk_power * hue_factor(h)
// Actual parameter values (v19):
// hk_weight = 0.370
// hk_power = 0.852
L += 0.370 * pow(C, 0.852) * hueFactor(h);What does this formula do?
- C (chroma): The saturation of the color. For gray, C=0; for a pure red, C is high.
- hk_weight = 0.370: The overall magnitude of the effect. A value of zero would turn H-K off entirely.
- hk_power = 0.852: The chroma exponent. Being less than 1 means the effect kicks in even at low chroma levels.
- hueFactor(h): A 4-harmonic Fourier series. The H-K effect is not equal across all hues -- it is stronger for blue and red, weaker for yellow. This series captures that profile.
The result: for a gray color, chroma is zero, so L is unchanged. But for a saturated color, chroma is high, so a positive amount is added to L. A saturated red gets a higher L value -- exactly as your eyes perceive it.
Why at This Exact Position?
Where the H-K correction is applied in the pipeline matters critically. Helmlab applies it after hue correction (so it operates on corrected hue angles) but before cubic L correction (so the remaining L-axis stages see the corrected L value). This ordering is intentional -- placing it at the end of the pipeline would break L-chroma interactions and cause inverse transform errors.
In Practice: Observing the H-K Effect with Helmlab
With the Helmlab npm package, you can directly observe how the H-K effect manifests in color coordinates:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Medium gray: sRGB (0.5, 0.5, 0.5)
const gray = hl.fromSRGB(0.5, 0.5, 0.5);
console.log('Gray L:', gray.L.toFixed(4));
// Saturated red: sRGB (0.9, 0.2, 0.2)
const red = hl.fromSRGB(0.9, 0.2, 0.2);
console.log('Red L:', red.L.toFixed(4));
// Saturated blue: sRGB (0.2, 0.2, 0.9)
const blue = hl.fromSRGB(0.2, 0.2, 0.9);
console.log('Blue L:', blue.L.toFixed(4));
// In Helmlab, the L values differ:
// Saturated colors receive a higher L than gray
// at the same luminance. This reflects perceived brightness.
// Measure the perceptual distance:
const dGrayRed = hl.deltaE(
{ r: 0.5, g: 0.5, b: 0.5 },
{ r: 0.9, g: 0.2, b: 0.2 }
);
console.log('Gray-Red deltaE:', dGrayRed.toFixed(4));Comparison with Oklab
When you examine the same colors in Oklab, the gray and the saturated red receive similar L values -- because Oklab does not model chroma's effect on lightness. It cannot reflect the brightness difference your eyes actually perceive.
The values in the table are representative. The key point is that Oklab gives all three colors the same L value, while Helmlab assigns higher L values to saturated colors. This difference -- the H-K shift -- reflects the brightness your eyes actually perceive.
Practical UI Impact
1. Button Hierarchy
A form has "Save" (saturated blue) and "Cancel" (gray) buttons. If you set both to the same Oklab L value, the blue button will appear brighter. If you want this to reinforce your visual hierarchy, fine -- but if you want equal visual weight, Oklab misleads you. In Helmlab, the same L value means genuinely the same perceived brightness.
2. Notification Badges
A saturated red "3 new messages" badge draws more attention than expected on a gray navigation bar -- not just because of the color difference, but because of the additional brightness from the H-K effect. If you design without knowing this, the badge carries an uncontrolled visual weight.
3. Dark Mode Accent Colors
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Dark mode background
const darkBg = hl.fromSRGB(0.12, 0.12, 0.14);
// Accent color: saturated purple
const accent = hl.fromSRGB(0.65, 0.30, 0.90);
// In Helmlab, the L difference includes the H-K effect
// so the contrast calculation reflects true perception
const contrast = hl.deltaE(
{ r: 0.12, g: 0.12, b: 0.14 },
{ r: 0.65, g: 0.30, b: 0.90 }
);
console.log('Background - Accent deltaE:', contrast.toFixed(3));4. Consistency Across Semantic Scales
Helmlab's semanticScale() function automatically accounts for the H-K effect at every step:
import { Helmlab } from 'helmlab';
const hl = new Helmlab();
// Red scale: every step is perceptually equidistant
const redScale = hl.semanticScale('#EF4444');
// Blue scale: same guarantee
const blueScale = hl.semanticScale('#3B82F6');
// In both scales, the 500-to-600 perceptual gap is equal
// Because the H-K effect is embedded in the L axis,
// no additional correction is neededThe Formula: 6 Parameters, 4 Harmonics
Helmlab's H-K model uses a total of 6 parameters:
- hk_weight (0.370): Overall effect magnitude
- hk_power (0.852): Chroma exponent
- hk_hue_mod: cos(h) coefficient -- which hues have a stronger effect
- hk_sin1: sin(h) coefficient
- hk_cos2: cos(2h) coefficient
- hk_sin2: sin(2h) coefficient
The last four parameters form a 4-harmonic Fourier series. This series captures the fact that the H-K effect varies in magnitude across hues. Experimental data shows that the effect is stronger for blue and red hues and weaker for yellow and green. The Fourier series models this profile with data-learned coefficients.
All of these parameters were optimized against more than 64,000 human color-difference observations. They are not hand-tuned -- they are values learned from data.
Why Other Spaces Cannot Simply Add This
In theory, an H-K correction could be added to any color space. In practice, three obstacles prevent it:
- Invertibility -- The H-K correction adds a chroma-dependent shift to the L axis. This shift must be exactly invertible (for the Lab-to-XYZ reverse transform). Helmlab achieves this with simple subtraction, but every stage in the pipeline must be mutually compatible.
- Parameter optimization -- H-K parameters cannot be optimized in isolation. They must be jointly optimized with the other 66 parameters in the pipeline, requiring a comprehensive experimental infrastructure.
- Standards compatibility -- CIE Lab is an ISO standard (ISO 11664-4). Changing it takes decades. Oklab is embedded in the CSS specification. "Patching" H-K onto these spaces would break backward compatibility.
Conclusion
The Helmholtz-Kohlrausch effect is a visual phenomenon known since the 19th century. Saturated colors appear brighter than neutral grays at the same luminance. This effect is ignored by Lab, Oklab, and CIEDE2000 -- because these spaces chose simplicity over completeness.
Helmlab makes a different choice: with its 72 parameters, it embeds the H-K effect directly into the L axis, correctly modeling perceptual brightness. When a saturated red and a gray share the same Helmlab L value, your eyes genuinely see the same brightness.
In UI design, this difference is concrete: button hierarchies, badge contrasts, dark mode accent colors, and palette steps are all directly affected by the H-K effect. Helmlab handles this in a 10.3 KB npm package:
npm install helmlabSource code: GitHub | Package: npm
This is post 6 of 16 in the Helmlab series. Next up: Pipeline Anatomy -- a look inside Helmlab's 13-stage transformation pipeline.