scalpel@labs: ~/glossary/css-color-formats.mdx7 sections

CSS Color Formats: hex, rgb, hsl, hwb and oklch

CSS can write the same colour five ways: `#hex`, `rgb()`, `hsl()`, `hwb()` and `oklch()`. They render identically; they differ in how easy each is to read and adjust. Hex is compact, HSL is intuitive, OKLCH is perceptual.

extension: Scalpel Colorupdated: 2026-08-14read_time: 3 min
less css-color-formats.mdx

Why it matters

Picking a format is not aesthetics, it is ergonomics. Storing brand colours? Hex. Hand-tuning a shade? HSL or HWB. Generating an accessible palette by maths? OKLCH. Reading a pixel from the screen? RGB, because that is what the eyedropper hands back. Each format has its place, and knowing which tool fits which job is the difference between a colour you can understand and one that feels like magic.

How it works

CSS colours are data. A colour is red, green and blue at some intensity, plus optional transparency. How you write it (as hex, as RGB channels, as a position on the hue wheel) does not change what the browser does. It paints the same pixel. The difference is how easy it is for you to read, edit and reason about.

A single colour in all five forms:

color: #38bdf8;       /* hex */
color: rgb(56 189 248);         /* rgb */
color: hsl(199 89% 60%);        /* hsl */
color: hwb(199 20% 10%);        /* hwb */
color: oklch(0.72 0.15 230);    /* oklch */

All five describe the same light blue. Which you choose depends on what you are doing next.

What does not matter

Hex is not "more precise" than rgb(). #38bdf8 and rgb(56 189 248) are the same 24-bit colour, bit for bit. Hex just writes it more compactly.

OKLCH is not "experimental and unsupported". It shipped in all three major browsers in 2023. The honest caveat is a fallback for older browsers, which you cover with a hex fallback declared just before the oklch() line.

Uppercase or lowercase hex, commas or spaces in rgb(): these are style choices, not technical differences. #FF0000 and #ff0000 are identical. Browsers accept both legacy rgb(255, 0, 0) and modern rgb(255 0 0).

The decision table

Use caseBest formatWhy
Store in a config or tokenHexShortest, easiest to copy
Adjust by hand in codeHSL or HWBChange one number, see the effect
Generate a palette by mathsOKLCHNumeric steps look visually even
Read a pixel from screenRGBThat is what the eyedropper returns
Mix old and new browsersHex (fallback) + OKLCHBrowser picks the first it understands

Alpha across formats

All five formats support optional transparency with the / syntax:

color: #38bdf8cc;           /* hex with alpha */
color: rgb(56 189 248 / 0.8);    /* rgb with alpha */
color: hsl(199 89% 60% / 0.8);   /* hsl with alpha */
color: hwb(199 20% 10% / 0.8);   /* hwb with alpha */
color: oklch(0.72 0.15 230 / 0.8); /* oklch with alpha */

Alpha is 0 (fully transparent) to 1 (fully opaque). 0.5 is roughly 50%. The / separator now works everywhere.

Code example

Converting between formats in CSS. The browser handles it, so you just pick your poison:

/* All one colour, different syntax */
:root {
  --primary: #3b82f6;        /* store once as hex */
}

.button-primary {
  background-color: var(--primary);      /* use it as-is */
}

.button-primary:hover {
  background-color: hsl(217 91% 60%);    /* hand-tune in HSL */
}

.button-accent {
  background: linear-gradient(
    135deg,
    #3b82f6,
    rgb(59 130 246 / 0.8)      /* rgb for readability in gradient */
  );
}

A conversion by hand, hex to RGB:

  • #38bdf8 → split into 38, bd, f8
  • 38 hex = 56 decimal, bd = 189, f8 = 248
  • So rgb(56 189 248)

Reverse it to go RGB to hex:

  • rgb(56 189 248) → 56 decimal = 38 hex, 189 = bd, 248 = f8
  • So #38bdf8

How Scalpel Color shows it

Open the extension. At the top, there is a dropdown menu labelled "Format". It defaults to hex, but you can switch to any of the five. Every swatch in the Picker shows its current colour in all five formats, and each row has a "Copy as" button to grab just that format. The colour you pick in the eyedropper returns as RGB first (that is what the operating system gives), but you can switch the display format and copy it as hex or HSL instead.

Sources