Which color format should you use?
Every format on this page describes the same thing, a point in a color space, but they are built for different jobs. Picking the right one makes a stylesheet easier to read and easier to change later.
HEX and HEX8
The default currency of design handoff. Compact, universally supported and easy to paste between Figma and code. HEX8 adds two digits of alpha (#101438cc is 80% opacity). The downside is that HEX is opaque to humans: you cannot look at #4e84ff and know how to make it 10% darker.
RGB
Useful when you are working with canvas, image data or JavaScript, where colors arrive as channel values. Modern CSS accepts space separated syntax with a slash for alpha, rgb(95 212 255 / 60%), and the older comma form with rgba() still works everywhere.
HSL and HWB
HSL (hue, saturation, lightness) made colors editable by hand, and it is still handy for quick tints. HWB (hue, whiteness, blackness) is the color-picker mental model: start with a pure hue, then mix in white or black. Both share a flaw: their lightness is not perceptual, so hsl(60 100% 50%) yellow looks far brighter than hsl(240 100% 50%) blue at the same "50%".
OKLCH and OKLab
OKLCH fixes that. Its L channel tracks perceived lightness, C is chroma and H is hue. Change the hue and the color stays just as light. That makes it the best format for design tokens, theme generation and anything you compute, which is why Tailwind 4 defines its whole palette in it.
:root {
--accent: oklch(72% 0.16 230);
/* a hover state that is exactly 8% darker, any hue */
--accent-hover: oklch(from var(--accent) calc(l - 0.08) c h);
}
OKLab is the rectangular version of the same space (a is green to red, b is blue to yellow). You rarely write it by hand, but it is the right space for mixing and gradients. color-mix(in oklab, ...) avoids the muddy gray middle you get when mixing in sRGB.
How the math works
Converting to OKLCH takes three steps. The sRGB channels are first decoded to linear light (undoing the gamma curve). Linear RGB is multiplied by a matrix into an LMS cone response, cube-rooted, and multiplied again into OKLab. Finally a and b are turned into polar coordinates to get chroma and hue. Going back runs the same steps in reverse. If the result lands outside the 0 to 255 range, the color exists in OKLCH but not on an sRGB screen, and the converter tells you it clamped it.
A note on CMYK
The CMYK row is a naive formula. Real print conversion depends on the paper, the ink and an ICC profile, so treat it as a starting point for a conversation with your printer, not a spec.
Frequently asked questions
Is OKLCH supported in browsers?
Yes. oklch() works in all current versions of Chrome, Edge, Safari and Firefox. For very old browsers, declare a HEX fallback on the line above the oklch() value.
Why does my OKLCH color show an out of gamut warning?
OKLCH can describe colors that sRGB screens cannot show. The converter clamps them to the nearest displayable values for HEX, RGB and HSL. Wide gamut displays can still render the original oklch() value.
Is the CMYK value print ready?
No. It is a simple mathematical conversion without an ICC profile. Use it for rough reference, and get final CMYK values from your printer or a proofed swatch book.
What is HEX8?
An eight digit hex code where the last two digits are alpha. #00000080 is black at roughly 50% opacity. All modern browsers support it.