Glossary

LCH color

LCH color is the cylindrical form of the CIE Lab color space, describing a color by lightness L, chroma C and a hue angle H in degrees. LCH stands for Lightness, Chroma, Hue. It keeps the lightness axis of Lab but replaces the rectangular a and b axes with an angle and a distance, which is easier to reason about when you want to rotate hue or adjust vividness. CSS supports it through the lch() function in CSS Color Module Level 4.

How it works

LCH is a coordinate conversion of Lab, not a different set of colors.

  • L: identical to Lab lightness, 0 to 100, with the same clamping. In CSS, 0% is 0 and 100% is 100.
  • C (chroma): the straight-line distance from the lightness axis, the square root of a squared plus b squared. It cannot be negative, and CSS clamps a negative value to 0. The spec says it does not exceed about 230 in practice, and 100% in CSS maps to 150.
  • H (hue): the angle from the positive a axis toward the positive b axis. 0deg is a purplish red, 90deg is a mustard yellow, 180deg is a greenish cyan and 270deg is a sky blue.

The hue angles are spaced by how different the colors look, not by RGB mixing, so they do not match HSL. Pure red is hsl hue 0 but LCH hue 40.9, and pure blue is HSL hue 240 but LCH hue 301.4.

When chroma is 0 (the spec uses a threshold of 0.0015), the color is a gray and the hue is powerless. A color with L of 0 or 100 shows as black or white.

function labToLch([L, a, b]) {
  const C = Math.hypot(a, b);
  let H = Math.atan2(b, a) * 180 / Math.PI;
  if (H < 0) H += 360;
  return [L, C, H];
}
const samples = {
  'hsl(0 100% 50%)': [54.29, 80.81, 69.89],
  'hsl(60 100% 50%)': [97.61, -15.75, 93.39],
  'hsl(240 100% 50%)': [29.57, 68.29, -112.03],
  '#3b82f6': [54.62, 8.76, -65.79],
};
for (const [name, lab] of Object.entries(samples)) {
  const [L, C, H] = labToLch(lab);
  console.log(`${name.padEnd(18)} lch(${L.toFixed(2)} ${C.toFixed(2)} ${H.toFixed(1)})`);
}
hsl(0 100% 50%)    lch(54.29 106.84 40.9)
hsl(60 100% 50%)   lch(97.61 94.71 99.6)
hsl(240 100% 50%)  lch(29.57 131.20 301.4)
#3b82f6            lch(54.62 66.37 277.6)

The Lab inputs are the values for each sRGB color from the Lab color page's conversion code.

What is the range of LCH values?

L runs from 0 to 100, chroma from 0 up to about 230, and hue from 0 to 360 degrees. Chroma has no hard upper limit, and the CSS spec treats 150 as the 100% reference. Hue angles outside the circle wrap, so 360deg and 720deg both equal 0deg.

Common pitfalls

  • Reusing HSL hue numbers: pure sRGB blue is hsl(240 100% 50%), but typing 240 as an LCH hue lands between greenish cyan (180deg) and sky blue (270deg). Pure sRGB blue sits near 301deg.
  • Picking chroma that sRGB cannot show: the spec example is that all colors at chroma 20 fit in sRGB at L 50, while some at 40 and 60 do not. Out-of-gamut colors are gamut mapped by the browser, so the displayed color is not the one you typed.
  • Trusting blue hues: between about 270 and 330 degrees the visual hue departs from what LCH predicts. Lowering the chroma of a saturated blue pushes it toward purple. The CSS spec presents Oklab-based OKLCH as the more perceptually uniform alternative.
  • Hue interpolation going the long way: CSS interpolates hue along the shorter arc by default, so a gradient from 350deg to 10deg crosses 0deg rather than sweeping through 180deg. Set a hue interpolation method if you need the longer arc.
  • Reading hue on grays: with chroma near 0 the angle is noise. A conversion library may return NaN or 0, and animating it makes grays jump color.

Related terms

  • Lab color — the rectangular form of the same space, with a and b axes
  • HSL — the simpler cylindrical model, with different hue angles
  • RGB — the channel model that LCH values are converted to for display
  • sRGB — the screen gamut that limits which LCH colors can be shown
  • HSV — another cylindrical model computed straight from RGB

See also