Colour notations and contrast

On screen every colour is a mix of red, green and blue, each from 0 to 255: that is RGB notation, and HEX is the same thing written in hexadecimal, two digits per channel. HSL and HSV describe the same colour more intuitively, as a hue on the colour wheel, saturation and lightness, which is why they are used to make lighter or darker variants.

Print works the other way round: it starts from white paper and takes light away with cyan, magenta, yellow and black inks, CMYK. The exact conversion depends on the paper and the press; the one shown here is the theoretical one, good for an idea but not for a print file.

WCAG contrast measures how well text stands out from its background, from 1:1 to 21:1, using relative luminance, which weighs green far more than blue, as the eye does. The guidelines ask for at least 4.5:1 for normal text and 3:1 for large text; 7:1 is level AAA.

Common mistakes

  • Choosing the text colour by eye: a full yellow looks strong but is very light, and white text on it is unreadable.
  • Expecting the computed CMYK to print like the screen: many bright RGB colours cannot be printed.
  • Forgetting transparency: a colour with alpha changes look and contrast depending on what lies beneath.

Frequently asked questions

What contrast is needed to be accessible?

WCAG 2 asks for 4.5:1 for normal text (level AA), 3:1 for large text of 24 px or 19 px bold, and 7:1 for level AAA.

What is the difference between HSL and HSV?

Both use hue and saturation. In HSL, 100% lightness is always white and 50% is the pure colour; in HSV, 100% value is the pure colour at full brightness.

How is a transparent colour written?

With an alpha channel: #185FA580 as eight-digit HEX, or rgba(24, 95, 165, 0.5). Alpha runs from 0, transparent, to 1, opaque.

How this calculation works

HEX #RRGGBB: each pair is a channel from 00 to FF. HSL: with max and min of the normalised channels, L = (max + min) / 2, S = (max − min) / (1 − |2L − 1|), H from the angle of the dominant channel. CMYK: K = 1 − max, C = (1 − R − K) / (1 − K) and so on. Contrast = (L1 + 0.05) / (L2 + 0.05), with luminance L = 0.2126 R + 0.7152 G + 0.0722 B on the linearised channels.