Convert a screen sRGB color into CIELCh — the cylindrical form of CIELAB built from Lightness, Chroma, and Hue. Because it is grounded in CIELAB, LCH separates a color into perceptually meaningful controls, which makes it ideal for building even, accessible palettes.
How it works
LCH is CIELAB expressed in polar coordinates, so RGB is first converted to Lab, then a* and b* are turned into chroma and hue:
- RGB to Lab — gamma-expand each sRGB channel to linear light, apply the sRGB-to-XYZ matrix under the D65 white, then the CIELAB nonlinearity to get
L*,a*,b*. - Lab to LCh:
L = L*
C = sqrt(a*^2 + b*^2)
H = atan2(b*, a*) in degrees, normalised to 0-360
L is unchanged; chroma is the radial distance from the neutral gray axis (how vivid the color is); hue is the angle around the wheel.
Example
Convert rgb(59, 130, 246):
- Lab ≈ L* 55.6, a* 17.6, b* −64.4
- C = √(17.6² + 64.4²) ≈ 66.8
- H = atan2(−64.4, 17.6) ≈ −75° → normalised to 285° (blue)
- Result:
lch(55.6% 66.8 285)
LCH vs HSL: perceptual uniformity
HSL is a geometric transformation of RGB. It separates colour into intuitive knobs, but it is
not perceptually uniform: two colors with the same HSL lightness can look dramatically different
in perceived brightness. A yellow at hsl(60, 100%, 50%) looks much lighter than a blue at
hsl(240, 100%, 50%), even though both have the same L value.
LCH is built on CIELAB, which was designed so that equal numeric differences correspond to approximately equal perceived differences. A step of 10 units in CIELAB lightness should look like the same visual step regardless of the starting hue. This makes LCH far more reliable for:
- Generating accessible color palettes where contrast ratios need to be consistent across hues
- Creating tonal scales that look visually even rather than lurching between perceived brightness levels
- Adjusting chroma (colorfulness) without inadvertently shifting perceived lightness
The trade-off is that LCH coordinates are less intuitive to read at a glance than HSL, and working in LCH requires either tool support or a converter like this one.
LCH chroma: open-ended scale
Unlike saturation in HSL, which is a percentage capped at 100%, chroma in LCH is open-ended. The maximum achievable chroma for sRGB colors is approximately 130, but most practical colors cluster below 80. High chroma values indicate saturated, vivid colors; a chroma near 0 is a near-neutral gray regardless of the hue value.
This open-endedness can be surprising at first — a vivid red may have a chroma of 100+, while a muted teal may have a chroma of 20. The key insight is that chroma represents actual colorfulness as a human eye perceives it, not a normalized percentage of the achievable gamut.
CSS lch() support
The CSS Color Level 4 specification includes lch() as a native color function. It takes the
form lch(L% C H), where L is 0–100, C is open-ended (typically 0–150 for sRGB gamut), and H
is the hue angle in degrees. Modern browsers support this syntax, and it can be used directly
in CSS stylesheets for color definitions.
One practical use: define a palette as a set of LCH colors with the same C and L values but varying H. Because LCH is perceptually uniform, the resulting colors will appear equally vivid and equally bright across hues — something that is very difficult to achieve by eyeballing HSL values.
Notes
Hue is undefined for true grays (chroma ≈ 0) and is reported as 0 in that case. The D65 white
point is used to match CSS lch(). For the closely related modern alternative with better hue
consistency, see the RGB to Oklch converter. Everything runs in your browser — nothing is uploaded.