Published

Colour contrast that actually passes WCAG

orange and black checkered illustration
Photo by Mika Baumeister on Unsplash

Low-contrast text is the single most common accessibility failure on the web, and it is also the easiest to fix, because the rule is a number and you can measure it. The difficulty is not the rule; it is knowing which pairs to check and what to change when one fails.

The rule

WCAG 2 measures contrast as a ratio between the relative luminance of two colours, from 1:1 (identical) to 21:1 (black on white). The thresholds:

Text AA AAA
Normal text (under 24px, or under 19px bold) 4.5:1 7:1
Large text (24px+, or 19px+ bold) 3:1 4.5:1
UI components and graphics (borders, icons, focus rings) 3:1 —

AA is the level almost every law and procurement standard asks for. Paste any foreground and background into the contrast checker and it reports the ratio and which levels pass.

The pairs people forget

Body text on a white background usually passes because someone checked it once. The failures hide elsewhere:

Fixing a failing pair without wrecking the palette

When a brand colour fails as text on white, do not just pick a random darker one. Generate the full lightness scale for the hue with the tint and shade scale and pick the first step that passes. You keep the hue, you gain a consistent scale to use for hover and active states, and the brand colour itself can still be used at large sizes or for non-text elements where 3:1 is enough.

If you are working from the other direction, the luminance scorer tells you the relative luminance of a single colour, which is handy for deciding whether black or white text belongs on it. Anything above roughly 0.18 luminance wants dark text.

Contrast is not the whole story

A pair can pass the ratio and still be hard to read. Red on green at 4.5:1 is technically fine and awful for the eight percent of men with a colour vision deficiency. Run your interface through the colour blindness simulator to check that nothing depends on hue alone: status colours need an icon or label as well, and charts need a pattern or direct labelling.

APCA and why the numbers disagree

WCAG 3 is introducing a new algorithm, APCA, which models perceived contrast more accurately: it accounts for font weight and size, and it knows that dark-on-light and light-on-dark are not symmetrical. Its scores run from 0 to about 106 and the guidance is roughly Lc 60 for body text and Lc 75 for smaller or thinner text. The APCA contrast checker gives that score for the same pair.

The two systems disagree at the edges. Some pairs pass WCAG 2 at 4.5:1 and score poorly on APCA, and dark-mode text often does the reverse. Today, WCAG 2 is what you will be audited against, so it must pass; use APCA as a second opinion for the pairs that only just pass.

The short version

Check every text colour you use, not just the body copy. Fix failures by moving along the lightness scale of the same hue, and check the result for colour-blind users as well as for contrast.

More from the blog

← All posts