Contrast is the accessibility requirement that affects the most people and gets checked the least. Low vision, ageing eyes, a phone in direct sunlight, a cheap monitor at a bad angle — all of them hit the same problem, and unlike most accessibility work, contrast is measurable. Either the number clears the threshold or it does not.
The three numbers
WCAG expresses contrast as a ratio between the lighter and darker of two colours. Pure black on pure white is 21:1, the maximum. Identical colours are 1:1.
| Requirement | Ratio | Applies to |
|---|---|---|
| AA, normal text | 4.5:1 | Body copy, labels, links, anything under 24px |
| AA, large text | 3:1 | 24px and up, or 18.66px and up if bold |
| AA, non-text | 3:1 | Icons, form borders, focus rings, chart elements |
| AAA, normal text | 7:1 | Stricter target, rarely mandated |
AA is the level referenced by most legislation and procurement requirements. AAA is a goal rather than a baseline — the guidelines themselves note it is not required for entire sites.
The tool Color Converter Open it →What counts as large text
This trips people up because the thresholds are specified in points, not pixels. Large text means 18pt or larger, or 14pt bold or larger. At the conventional 96 dpi that works out to 24px, or 18.66px when bold.
The practical consequence: a heading at 20px regular is not large text and needs the full 4.5:1, even though it is visibly bigger than the paragraphs around it. Designers routinely assume any heading qualifies. Most do not.
How the ratio is calculated
Worth understanding, because it explains results that otherwise look wrong. Each channel is converted from sRGB to linear light, weighted by how sensitive human vision is to it — green counts for 71.5%, red for 21.3%, blue for just 7.2% — and summed into a relative luminance. The ratio is then (L₁ + 0.05) ÷ (L₂ + 0.05).
Two things follow. First, blue contributes almost nothing to perceived lightness, which is why saturated blue text on black fails badly despite looking bright. Second, the 0.05 constant models ambient screen glare, and it compresses ratios at the dark end — dark greys separate less than you would expect.
A worked example
Say a brand uses amber #f0a83c on deep navy #0a0e17. That pairing measures about 9.4:1 — comfortably AAA, no problem.
Now the same amber on white: 2.1:1. It fails everything, including the 3:1 non-text threshold. The colour has not changed; the background has. This is why a brand palette cannot be declared accessible in the abstract, only in specific pairings.
To use that amber as text on white you have to darken it. Dropping the lightness in HSL while keeping hue and saturation gets you to roughly #8a5a00 at 4.6:1 — recognisably the same brand colour, now legible. Working in HSL rather than hex makes this a one-number adjustment.
Keep the bright version for large headings, borders and icons where 3:1 applies, and the darkened version for body text. One brand colour, two tokens, both compliant.
The places it usually fails
- Placeholder text. The default in most browsers is a light grey that fails against white. Placeholders are also not a substitute for labels, so this often accompanies a second problem.
- Muted secondary text. Captions, timestamps, helper text — deliberately de-emphasised, and the point where designers push grey too far. It is still text and still needs 4.5:1.
- Text over images. The ratio changes with every pixel behind it. A scrim or solid panel behind the text is the reliable fix; testing one frame of a hero image is not.
- Focus indicators. A default focus ring on a dark background frequently fails the 3:1 non-text requirement. Keyboard users depend on it entirely.
- Form borders. A 1px light-grey border on white is often around 1.4:1, leaving the field boundary invisible to anyone with reduced contrast sensitivity.
- Charts. Adjacent series colours need 3:1 against each other and their background, and should not rely on hue alone — around 8% of men have some form of colour vision deficiency.
Disabled controls
Disabled elements are exempt from the contrast requirements. That exemption is often stretched: if a control is exempt but nobody can read it, the interface is still failing people even while passing the audit. Keeping disabled states legible costs nothing.
What contrast does not cover
Passing 4.5:1 does not make text readable. Line length beyond about 80 characters, cramped line height, very light font weights at small sizes and pure black on pure white — which many people with dyslexia find harsh — all hurt readability while scoring perfectly. Contrast is a floor, not a measure of quality.
A note on what is coming
The current formula has known weaknesses, particularly around dark backgrounds and thin fonts, where it can pass pairings that are hard to read and fail ones that are fine. Work on a replacement — a perceptual model known as APCA — has been underway for the draft of WCAG 3 for some years. It is not a standard yet and nothing you must comply with today references it. Build against the current ratios; watch the other work without acting on it.