Cheatsheet

Color Formats Cheatsheet

This cheatsheet lists every color notation CSS accepts, with the exact syntax, value ranges and what the browser prints back. It is for developers who copy a color from a design file and need it in another format. The common confusion is alpha: hex puts it in the last two digits, while rgb() and hsl() take a percentage or a number after a slash. Background on the hex form itself is in the Hex color term, and the color space behind most of these formats is sRGB.

Quick reference

Notations at a glance

Notation Example Components Gamut
Hex `#3366cc` red, green, blue as 2 hex digits each sRGB
`rgb()` `rgb(51 102 204)` 0-255 or 0%-100% per channel sRGB
`hsl()` `hsl(220 60% 50%)` hue, saturation, lightness sRGB
`hwb()` `hwb(220 20% 20%)` hue, whiteness, blackness sRGB
`lab()` `lab(50% 40 59.5)` lightness, a axis, b axis Covers all visible colors
`lch()` `lch(50% 70 40)` lightness, chroma, hue Covers all visible colors
`oklab()` `oklab(62% 0.15 0.08)` lightness, a axis, b axis Covers all visible colors
`oklch()` `oklch(62% 0.2 29)` lightness, chroma, hue Covers all visible colors
`color()` `color(display-p3 1 0 0)` a named space plus three numbers Depends on the space
`color-mix()` `color-mix(in srgb, red 50%, blue)` two colors and a mixing space Result of the mix
Keyword `tomato` one of 148 named colors sRGB

The syntax comes from CSS Color Module Level 4, which was a W3C Candidate Recommendation Draft dated 30 September 2026 when this sheet was written.

Hex lengths

A hex color is # followed by 3, 4, 6 or 8 hex digits. Letter case does not matter.

Digits Form Example Result in Chromium 153
3 `#rgb` `#f00` `rgb(255, 0, 0)`
4 `#rgba` `#f008` `rgba(255, 0, 0, 0.533)`
6 `#rrggbb` `#ff0000` `rgb(255, 0, 0)`
8 `#rrggbbaa` `#ff000080` `rgba(255, 0, 0, 0.5)`
5 or 7 none `#12345` Invalid, the declaration is dropped

Short forms double each digit, so #f08 is #ff0088. The 4-digit alpha 8 becomes 88, which is 136 of 255 and prints as 0.533, not 0.5.

Alpha as a percentage and as hex

Opacity Hex pair Opacity Hex pair
100% `ff` 40% `66`
90% `e6` 30% `4d`
80% `cc` 25% `40`
75% `bf` 20% `33`
70% `b3` 10% `1a`
60% `99` 5% `0d`
50% `80` 0% `00`

Ranges of each function

Function Channel 1 Channel 2 Channel 3 Alpha
`rgb()` 0-255 or 0%-100% same same 0-1 or 0%-100%
`hsl()` hue in degrees saturation % lightness % 0-1 or 0%-100%
`hwb()` hue in degrees whiteness % blackness % 0-1 or 0%-100%
`lab()` L 0%-100% a, about -125 to 125 b, about -125 to 125 0-1 or 0%-100%
`oklch()` L 0-1 or 0%-100% chroma, about 0 to 0.4 hue in degrees 0-1 or 0%-100%

The a, b and chroma bounds for Lab-type spaces are not hard limits in the spec; they describe where real colors sit.

Spaces accepted by color()

Keyword Space
`srgb` sRGB with gamma encoding
`srgb-linear` sRGB without gamma
`display-p3` Display P3, wider than sRGB
`a98-rgb` Adobe RGB (1998)
`prophoto-rgb` ProPhoto RGB
`rec2020` ITU-R BT.2020-2
`xyz`, `xyz-d50`, `xyz-d65` CIE XYZ, with `xyz` meaning D65

Special keywords

Keyword Meaning
`transparent` Computes to `rgba(0, 0, 0, 0)`
`currentcolor` The element's own `color` value
`none` A missing component inside `hsl()`, `lab()`, `oklch()` and similar

Common patterns

Write the same color in each format

.a { color: #3366cc; }
.b { color: rgb(51 102 204); }
.c { color: hsl(220 60% 50%); }
.d { color: hwb(220 20% 20%); }

All four describe the same sRGB color. A script that converted #3366cc gave rgb 51 102 204, hsl(220 60% 50%) and hwb(220 20% 20%). Pick hsl() when you want to adjust lightness by hand.

Convert hex to HSL in plain JavaScript

const hex = '#3366cc';
const [r, g, b] = [1, 3, 5].map(i => parseInt(hex.slice(i, i + 2), 16));
const R = r / 255, G = g / 255, B = b / 255;
const max = Math.max(R, G, B), min = Math.min(R, G, B), d = max - min;
const l = (max + min) / 2;
const s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
let h = max === R ? ((G - B) / d) % 6 : max === G ? (B - R) / d + 2 : (R - G) / d + 4;
h = (h * 60 + 360) % 360;
console.log('hsl(' + Math.round(h) + ' ' + Math.round(s * 100) + '% ' + Math.round(l * 100) + '%)');
console.log('hwb(' + Math.round(h) + ' ' + Math.round(min * 100) + '% ' + Math.round((1 - max) * 100) + '%)');

Output:

hsl(220 60% 50%)
hwb(220 20% 20%)

Whiteness is the smallest channel and blackness is one minus the largest. The Color Converter does the same conversion between HEX, RGB, HSL, HSV and CMYK without code.

Add transparency

.a { color: #ff000080; }
.b { color: rgb(255 0 0 / 50%); }
.c { color: rgba(255, 0, 0, .5); }

Chromium 153 serialized all three as rgba(255, 0, 0, 0.5). Use the slash form in new code and the comma form only when you must support old parsers.

Mix two colors

.mix { color: color-mix(in srgb, red 50%, blue); }

Computed value in Chromium 153:

color(srgb 0.5 0 0.5)

The in keyword picks the space where the mix happens, so the same two colors give a different result in oklch than in srgb.

Derive a color from another with relative syntax

.half { color: rgb(from #336699 r g b / 50%); }

Computed value in Chromium 153:

color(srgb 0.2 0.4 0.6 / 0.5)

The from keyword exposes the source color's channels as r, g and b, here to set half opacity without changing the color.

Use a wide-gamut color with a fallback

.hero {
  background: rgb(255 0 0);
  background: color(display-p3 1 0 0);
}

A browser that does not understand color() drops the second line and keeps the sRGB fallback. Chromium 153 kept color(display-p3 1 0 0).

Pitfalls

  • Four-digit hex alpha looks rounded wrong: #f008 is 136 out of 255, which is 0.533, not 0.5. Write #ff000080 for exactly half.
  • Mixing legacy and modern separators: rgb(255, 0, 0 / .5) is invalid and Chromium 153 ignored the declaration. Use all commas with rgba(), or all spaces with a slash.
  • Expecting an out-of-range channel to fail: rgb(300 0 0) is accepted and clamped, and Chromium 153 returned rgb(255, 0, 0).
  • Hex with 5 or 7 digits: #12345 is dropped, so the property falls back to the inherited or default value, which can turn text black.
  • Reading computed values as the source text: tomato computes to rgb(255, 99, 71) and hsl(120deg 100% 25%) to rgb(0, 128, 0). Compare colors by their computed form, not by string.
  • Assuming hsl() lightness is perceptual: two colors with the same hsl() lightness can look very different in brightness. oklch() lightness tracks perception much better, which matters for contrast.
  • Forgetting the legacy comma rules: rgb() and hsl() still accept commas, but the legacy form cannot use none or mix numbers and percentages.
  • Using hex for a P3 color: hex can only hold sRGB values. A saturated Display P3 color needs color(display-p3 …) or oklch().

Related ZipKit tools

  • Color Converter — converts colors between HEX, RGB, HSL, HSV and CMYK
  • Color Picker — picks a color with a visual spectrum and copies it as HEX, RGB, HSL or CMYK
  • Color Contrast Checker — checks WCAG AA and AAA contrast ratios for text
  • WCAG Contrast Matrix — tests a whole palette to find AA and AAA compliant pairs

Related cheatsheets