HSL lightness is not true perceived brightness 🎨
The L value in HSL is only a geometric quantity within that color model. It is not defined so that colors with the same L are perceived by humans as equally bright.
A typical example:
- a strong yellow
- a strong blue
can have the same HSL L value, yet yellow will still appear much brighter than blue.
Why is that?
HSL is ultimately based on the usual RGB color space. RGB is practical for displays, but it is not perceptually uniform.
That means:
- equal numerical changes in RGB or HSL
- do not produce equally large visual changes
In particular, our eyes are not equally sensitive across all hues:
- yellow/green often appears very bright
- blue often appears much darker
- even when the technical values look similar
What you need instead
If you want colors to be truly equally bright, you need a more perceptually uniform color space. There are mathematical models for that.
The most important ones are:
-
CIELAB / L*a*b*
L*is much closer to perceived lightness- much better than HSL
-
CIELUV
- similar purpose
- slightly different focus
-
OKLab / OKLCH
- more modern
- often very well suited for UI, web, and design work
- in many cases, the best practical choice today
The core idea: “luminance” vs. “perceived lightness”
1. Physical or technical brightness: relative luminance
For an sRGB color, you can first compute the relative luminance $Y$.
If R, G, and B are linear RGB values in the range from 0 to 1, then:
$$
Y = 0.2126 R + 0.7152 G + 0.0722 B
$$
Important: these are linear RGB values, not the raw 8-bit sRGB values you typically use in CSS.
So first, sRGB must be linearized. For an sRGB channel $c_{srgb}$:
$$
c_{lin} =
\begin{cases}
\frac{c_{srgb}}{12.92}, & c_{srgb} \le 0.04045 \
\left(\frac{c_{srgb}+0.055}{1.055}\right)^{2.4}, & c_{srgb} > 0.04045
\end{cases}
$$
This luminance is important for things like:
- contrast calculations
- WCAG
- technical comparisons of brightness
But equal luminance is still not perfectly the same as “equally bright as perceived.”
2. Perceived brightness: perceptual lightness
For this, CIELAB uses the quantity $L^*$.
From the relative luminance $Y$ and the reference white $Y_n$, it is approximately calculated as:
$$
L^* = 116 \cdot \left(\frac{Y}{Y_n}\right)^{1/3} - 16
$$
for larger values; more precisely, the full definition is piecewise. But the main idea is:
- it is not linear
- it is adjusted to human perception
Equal $L^*$ values are much closer to “equally bright” than equal HSL L values.
Especially relevant for CSS today: OKLCH
For practical work on the web, OKLCH is often the best answer.
OKLCH consists of:
- L = perceived lightness
- C = chroma / colorfulness
- H = hue angle
So it is similar to HSL in terms of intuition, but much better aligned with perception.
Advantage
If you use the same L value in OKLCH, colors are much more likely to appear equally bright.
Example in CSS:
color: oklch(0.7 0.15 30);
color: oklch(0.7 0.15 120);
color: oklch(0.7 0.15 260);
Here, the lightness set by 0.7 is much more consistent than in comparable HSL colors.
So: is there a mathematical way to do this?
Yes. In fact, there are several—depending on what exactly you mean by “equally bright”:
-
Equal technical luminance
- using linear RGB and
$$
Y = 0.2126 R + 0.7152 G + 0.0722 B
$$ - good for contrast and measurable brightness
- using linear RGB and
-
Equal perceived lightness
- using CIELAB
L*or, better, OKLab/OKLCHL - good for design, UI, and color palettes
- using CIELAB
Practical recommendation
If your goal is:
“Colors should appear equally bright in an interface”
Use OKLCH instead of HSL.
“I want mathematically correct contrast checks”
Work with relative luminance.
“I want an older, well-established color model”
Then CIELAB is a good choice.
Why HSL is still often used
HSL is popular because it feels intuitive:
H= hueS= saturationL= light/dark
But that L is more of a model parameter than a true measure of visual lightness.
HSL can still be useful for:
- simple color variations
- quick prototypes
- small adjustments
But not if you want colors that are precisely equal in perceived brightness.
Short version
Yes, there are mathematical models for this.
If colors should really appear equally bright, HSL is not suitable.
The best options are:
- OKLCH for practical CSS and UI work
- CIELAB / OKLab if you want to work in perceptually meaningful color spaces more rigorously
If you want, I can also show you next:
- why HSL lightness is defined the way it is
- how to convert an HSL color into relative luminance
- how to build an equal-lightness color palette in CSS using OKLCH