Skip to content
PaletteViva

HEX, RGB, HSL and OKLCH explained

Four ways of writing the same colour, each invented to solve a different problem. Knowing which one to reach for removes a surprising amount of friction from design and front-end work — and explains why two values that look identical on your screen are not the same number.

HEX

#4a7f61 is three pairs of hexadecimal digits: red 4a, green 7f, blue 61, each from 0 to 255. It is the most compact way to write an sRGB colour, which is exactly why it spread — early CSS had no other notation and the web has never let go.

  • Shorthand: #4a7f61 can be written #4f6 only when each channel's two digits are identical. Many tools expand it for you; do not assume a three-digit value is rounded the way you expect.
  • Alpha: an eight-digit form such as #4a7f6180 adds opacity. Widely supported now, but a codebase that mixes it with rgba() is harder to search.
  • Its weakness: it is opaque to humans. Nobody reads #4a7f61 and visualises a colour, and nobody can lighten it by a predictable amount, because the three channels are not perceptually spaced.

RGB

The same three channels as hex, written as numbers: rgb(74 127 97). In CSS they run 0–255 by default, 0–1 with a percentage-free number syntax in modern browsers, and 0%–100% with percentages. That flexibility is a quiet source of bugs: 74 and 74% are different colours, and both are valid.

RGB is the format to use when you are computing, and the format to avoid when you are reasoning. Anything you would describe as "make this darker" or "make it warmer" is awkward arithmetic in RGB and straightforward in a hue-based space.

HSL and HSV

HSL re-describes RGB as hue (the angle around the colour wheel), saturation (how far from grey) and lightness (how close to white or black): hsl(150 27% 39%). HSV swaps lightness for value and puts white at S = 0 instead, which is why colour pickers built on HSV feel different to move around.

HSL is the format designers reach for first, because "same hue, less saturation" is a real design move and in HSL it is one number. The trap is that HSL is not perceptually uniform: at fixed saturation and lightness, yellow and blue have wildly different contrast, so a set of HSL shades that looks evenly stepped in a swatch grid will not look evenly stepped on a page. Use it, and do not trust it for even steps.

OKLCH — the perceptual one

OKLab and its cylindrical form OKLCH are perceptual spaces: equal numeric changes look like equal visual changes, across the whole hue circle. Written as oklch(51.2% 0.061 152) — lightness, chroma, hue — it is what you want whenever the requirement is "even steps between shades" or "same lightness, different hue".

  • Gradients interpolate far more evenly in OKLCH than in sRGB, because interpolation happens between perceptually spaced endpoints rather than between device channels. Purple-to-green is the classic case that turns to mud in RGB.
  • Design systems now derive scales in OKLCH: pick a hue and chroma, then step lightness evenly, and the steps look evenly spaced.
  • Wide-gamut colour is only expressible this way. oklch() can describe colours outside sRGB, which is the point of P3 displays.
  • The cost: it is young. Support is broad in 2026, but older build tools, email clients and print workflows may not take it.

Why the same colour reads as two different values

A colour has no single correct number until you say which space it is in. Three factors cause most of the confusion:

  1. The colour space of the source. A Display P3 photo can contain colours sRGB cannot represent. Converted to sRGB, those colours are clipped, and two nearby pixels can collapse onto the same hex. That is why the same file reports different values in different tools — see sRGB vs Display P3 .
  2. Rounding. Both HSL and OKLCH carry a hue angle and a small chroma; rounding them for display loses information that a round trip will not recover exactly.
  3. Compression. JPEG and WebP are lossy. The pixel you sample may be a step or two from the pixel the designer exported.

Which one should you actually use?

Handing a value to another person
Hex. It is short, unambiguous in an sRGB workflow, and pastes into every tool without an explanation.
Designing a scale of shades
OKLCH. Step the lightness evenly, then convert outward for the platforms that need sRGB.
Writing CSS today
Whichever your consumers support. Hex and rgb() are safe everywhere; oklch() is the better tool where it is supported.
Describing a colour out loud
A name. "Deep teal" communicates instantly and imprecisely, which is usually the right trade for a conversation — see the colour name finder below.
Print
None of these. CMYK with an ICC profile for your specific press is the only route to a predictable printed colour; a screen-to-CMYK conversion without a profile is an approximation.

To read all of these at once from a colour inside an image, use the image color picker — it shows hex, RGB and HSL together, with OKLCH and HSV one click away. For a name instead of a code, the color name finder gives you the closest name and how close it really is. And if you want the vocabulary for how a whole palette is derived, read how palette extraction works .