Contrast ratio runs from 1:1, where the text is invisible against its background, to 21:1, which is pure black on pure white. Between those, four thresholds matter.
| Ratio | Level | Applies to |
|---|---|---|
| 4.5:1 | AA | Normal body text. Treat this as the floor. |
| 3:1 | AA | Large text, and UI components and focus rings. |
| 7:1 | AAA | Body text, enhanced. |
| 4.5:1 | AAA | Large text, enhanced. |
AA is the level most accessibility legislation references, so 4.5:1 for body text is the practical requirement, not an aspiration.
What counts as "large text"
This is the part people get wrong, usually in their own favour.
Large means 24 px or above, or 19 px or above if it is bold. (The spec says 18.66px and 14px in points; the pixel figures are the usual rounding.) That is genuinely large — bigger than almost all body copy, bigger than most subheadings.
The trap is reasoning backwards: your grey-on-white sits at 3.4:1, that fails AA for normal text, so you decide 18 px counts as large and move on. It does not, and a screen reader user or someone with low vision does not care what you decided. If the ratio fails, change the colour.
Where the number comes from
Contrast ratio is computed from relative luminance — how much light each colour emits, weighted by how sensitive human vision is to red, green and blue. Green counts for about 72% of perceived brightness, red 21%, blue 7%.
That weighting explains something that otherwise looks wrong. Pure blue on white gives 8.6:1 and passes everything, while pure yellow on white gives 1.07:1 and is essentially invisible — despite both being "a saturated colour on white". Blue is dark to the eye; yellow is almost as bright as white. Saturation has nothing to do with it.
So you cannot eyeball this. You have to measure it, which is why the colour converter here shows the ratio against black and white text and whether each threshold passes as you change the colour.
The two things the ratio does not tell you
1. It says nothing about colour blindness
Red text and green text can both have excellent contrast against a white background and be completely indistinguishable from each other to roughly 8% of men. The ratio is measuring each colour against its background, not colours against each other.
The rule that follows: never use hue alone to carry meaning. Add an icon, a label, a pattern, a position. "Click the green button" is an instruction some of your users cannot follow.
2. Passing is a floor, not a goal
Text at exactly 4.5:1 is compliant and still tiring to read for a long stretch. If you are setting body copy for an article, aim higher — 7:1 or better is comfortable, and it costs you nothing but a slightly darker grey.
The fashion for light grey body text on white is the single most common accessibility failure on the modern web, and it is entirely self-inflicted. #999 on white is 2.8:1. It fails.
Cases that catch people
- Placeholder text. It is text. It needs 4.5:1. Browser defaults usually do not meet it, so if you rely on placeholders to label fields — which is its own problem — you have two failures stacked.
- Disabled controls. Exempt from the requirement, which is a genuine gap in the spec rather than permission to make them illegible.
- Text over images. The ratio has to hold against the worst pixel behind the text, not the average. A scrim or a solid panel is usually the only reliable fix.
- Focus indicators. Need 3:1 against what is next to them. The default browser outline usually passes; the
outline: nonepeople add to "clean it up" is a real accessibility regression. - Logos. Genuinely exempt.
- Dark mode. Checking the light theme and assuming the dark one is fine is how half of dark modes ship broken. They are separate colour systems and need separate checks.
A shortcut that works
Rather than testing colours one at a time until something passes, fix the hue and sweep the lightness. Pick your brand hue, then generate a scale from very light to very dark, and check the ratio at each step. You end up with a small set of known-good pairings — this text colour on that background — instead of re-deciding every time.
That is how design systems handle it, and it is much faster than the guess-and-check loop.
The fastest way to check a specific pair is the colour converter — paste a hex value and it gives you the ratio against black and white text with each threshold marked pass or fail. It also generates the lightness scale described above, so you can find the step where your brand colour starts passing instead of guessing at it.
If you found yourself wondering why the tool offers HSL at all when you think in hex, that is worth ten minutes: HEX, RGB and HSL explained covers why hex is fine for storing a colour and terrible for adjusting one — which is exactly the problem you hit the moment a contrast check fails.
Frequently asked questions
What contrast ratio is required for accessibility?
4.5:1 for normal body text and 3:1 for large text to meet WCAG AA, which is the level most accessibility legislation references. AAA asks for 7:1 on body text and 4.5:1 on large text.
What counts as large text for contrast purposes?
24px or larger, or 19px or larger if bold. That is bigger than most body copy and most subheadings, so in practice the 4.5:1 requirement applies to nearly all the text on a typical page.
Does a good contrast ratio mean my colours are colour-blind safe?
No. Contrast measures each colour against its background, not against other colours. Red and green text can both pass and still be indistinguishable to about 8% of men. Never use hue alone to carry meaning.
Is grey text on white accessible?
It depends on the grey. #999 on white is 2.8:1 and fails. #767676 on white is about 4.5:1 and just passes. Light grey body text is the most common accessibility failure on the modern web.
Do I need to check contrast separately in dark mode?
Yes. Light and dark themes are separate colour systems and a pairing that passes in one routinely fails in the other. Checking only the light theme is how most broken dark modes ship.
Last updated September 19, 2026