The idea in plain language
A Contrast ratio A measure from 1:1 to 21:1 of how different two colours are in brightness, calculated from their relative luminance. WCAG 2.2 asks for at least 4.5:1 for normal text and 3:1 for large text so that people with low vision can read it. See the glossary compares how light two colours are. It runs from 1:1 (the same colour twice, unreadable) to 21:1 (black on white). The ratio is calculated from each colour’s relative luminance – how bright it looks to the eye, with green counting most and blue least – using the formula (lighter + 0.05) ÷ (darker + 0.05). Hue does not matter: a red and a green of the same lightness can be nearly impossible to tell apart.
What WCAG 2.2 asks for
The Web Content Accessibility Guidelines set minimum ratios so that people with low vision or a poor screen can still read the page:
| What | AA (the usual target) | AAA (enhanced) |
|---|---|---|
| Normal text | 4.5:1 | 7:1 |
| Large text (24px, or about 18.7px bold) | 3:1 | 4.5:1 |
| Icons, input borders, focus rings (non-text) | 3:1 | – |
Large text gets a lower threshold because bigger letters stay legible at lower contrast. Note the trap: bold alone does not make text large. A 16px bold button label still needs 4.5:1.
Worked example: four real colour pairs
We ran these pairs through our Color Contrast Checker, which uses the WCAG formula:
| Text | Background | Size | Ratio | AA result |
|---|---|---|---|---|
#767676 grey |
#FFFFFF white |
16px | 4.54:1 | Pass (just) |
#9CA3AF light grey |
#FFFFFF white |
16px | 2.54:1 | Fail |
#9CA3AF light grey |
#FFFFFF white |
24px | 2.54:1 | Fail (below 3:1) |
#FFFFFF white, bold |
#C4623A terracotta |
16px | 4.07:1 | Fail |
#FFFFFF white, bold |
#A34A28 dark terracotta |
16px | 5.89:1 | Pass |
Two lessons hide in this table. First, the popular “placeholder grey” #9CA3AF fails even at large sizes. Second, a brand colour can be one shade away from passing: this site uses the darker #A34A28 for buttons and the lighter #C4623A only for large decorative areas.
Fixing a colour that fails
Because contrast depends on lightness, the cleanest fix is to keep the hue and change only how light the colour is. The checker’s suggestion feature does exactly that: for #9CA3AF on white with a 4.5:1 target it proposes #6F7681, which measures 4.58:1 – still a cool grey, now readable. Working in a perceptual colour space such as OKLCH A CSS colour space that describes a colour by perceptual lightness (L), chroma (C, colourfulness) and hue (H). Because equal steps look roughly equal to the eye, it is useful for building colour palettes and smooth gradients, written as oklch(70% 0.15 250). See the glossary makes this easy by hand, because you can lower the L value and leave chroma and hue alone.
Common mistakes
- Checking only the brand colour, not every state. Hover, disabled and placeholder colours need checking too (disabled controls are exempt, placeholders are not).
- Forgetting borders and icons. An input whose border is 1.5:1 against the page is hard to find; WCAG 1.4.11 asks for 3:1.
- Text on images or gradients. Measure against the lightest part behind the text, as the next lesson shows.
Try it
Open the Color Contrast Checker, paste your text and background colours, set the font size, and use the suggestion to get the nearest passing colour. Then check your palette’s lighter and darker shades with the Color Converter.