4.5:1, 3:1, 7:1 — where those numbers come from, how the ratio is calculated from two hex codes, what counts as "large text", and how to fix a failing pair without surrendering your brand colour. The whole standard, in working terms.
Contrast requirements are the most mechanical part of accessibility: two colours go in, one ratio comes out, and the standard sets thresholds the ratio must clear. Yet confusion is everywhere — about which threshold applies to which text, about whether logos and disabled buttons are exempt, and about why a pair that "looks fine" keeps failing audits. Almost all of it dissolves once you see the actual formula and the actual table of requirements.
This guide gives you both, then deals with the practical heart of the matter: your brand colour fails, the hue is non-negotiable, and you still have to ship an accessible site. There is a systematic way out of that bind, and it runs along one axis — lightness.
Key takeaways
- AA (the normal legal/design target): 4.5:1 for body text, 3:1 for large text and for essential UI graphics.
- AAA (enhanced): 7:1 for body text, 4.5:1 for large text — aim for it on long-form reading surfaces where you can.
- "Large" means at least 24px, or about 18.7px (14pt) and bold. Nothing else earns the lower threshold.
- The ratio is computed from relative luminance, not from how different two hues feel.
The formula, once and for all
WCAG contrast compares relative luminance — a number between 0 (black) and 1 (white) that approximates how bright a colour appears, weighted the way human vision is: green contributes most, blue least. Each sRGB channel is first linearised (undone from its gamma encoding), then combined as L = 0.2126×R + 0.7152×G + 0.0722×B. The ratio is then (Llighter + 0.05) / (Ldarker + 0.05), which is why the maximum is exactly 21:1 — pure white against pure black — and why the ratio is symmetric: text colour on background scores identically to background on text colour.
That blue weight of 0.0722 surprises people: saturated blues are luminance-poor, so blue text on black is far worse than it feels, while yellow — red plus green, the two heavy channels — is luminance-rich and nearly unusable on white at any saturation. If a pairing's failure surprises you, it is usually the luminance arithmetic disagreeing with your intuition about hue.
The requirements table
| Element | AA | AAA | Notes |
|---|---|---|---|
| Normal text (below large thresholds) | 4.5:1 | 7:1 | The everyday rule for body copy, links, form labels |
| Large text (≥24px, or ≥18.7px bold) | 3:1 | 4.5:1 | Headings, big numerals, hero copy |
| UI components & meaningful graphics | 3:1 | — (no AAA rule) | Input borders, icons that carry meaning, chart elements, focus indicators — against adjacent colours |
| Incidental text (logos, decorative, disabled controls, text in photos) | No requirement | No requirement | Exempt by the standard — but a disabled control nobody can perceive is still a design problem |
Two clarifications auditors repeat daily. First, the requirement applies to the text's colour against its immediate background — gradients and images behind text must pass at their worst point, not their average. Second, hover and focus states are not exempt: a link that passes at rest and fails on hover fails, full stop.
Fixing a failing brand colour along the lightness axis
When a brand colour fails as text on white — and most vivid brand colours do; a typical brand orange at #FF7A29 scores roughly 2.5:1 — the hue is usually sacred and the saturation negotiable, which leaves lightness as the working axis. The procedure is mechanical:
- Note the failing ratio and the target (4.5:1 for body text on your background).
- Convert the colour to OKLCH or HSL and hold hue constant. In OKLCH, walk lightness down in steps of about 0.05; in HSL, steps of 5 points.
- Re-check the ratio at each step. For the orange above against white, the colour typically needs to travel from lightness ~0.70 to ~0.52 in OKLCH terms — a visibly deeper, richer orange, recognisably the same brand.
- Bank the result as a separate token. The original brand colour keeps its jobs (logos, large graphics, accents at 3:1 where it may already pass); the darkened variant becomes "brand text". Two tokens, one hue, no arguments.
- Apply the same walk in reverse for dark backgrounds: lighten step by step until the ratio clears against your dark surface colour — not against pure black, unless that truly is the surface.
What not to do is fiddle with both colours at once — you lose track of which change bought which ratio — or to accept a pass at 3:1 meant for large text and use it for 14-pixel body copy.
Beyond the number: what the ratio cannot see
The WCAG formula is a model, and it has known blind spots. It can rate some dark-mode pairings as passes that many readers find glaring, and some light pairings as failures that read comfortably — the upcoming WCAG 3 work on perceptual contrast (APCA) addresses exactly this, but it is not yet the normative standard. Treat the ratio as a floor, not a finish line: check real text, at real sizes, on a real screen, and give long reading surfaces more margin than the minimum wherever your palette allows it.
Mistakes and pitfalls
Testing text against the page background instead of its actual background
Text sitting on a card, banner or button must be measured against that surface, not the page behind it. Audits fail on exactly this — a passing ratio measured against the wrong neighbour.
Averaging a gradient
A headline over a gradient that fades from dark to light passes at the dark end and fails at the bright end. The requirement applies everywhere the text sits; test the worst segment, or put a solid scrim behind the text.
Assuming grey text is 'subtle and safe'
Mid-grey on white is the web's most common contrast failure (#777 on white is about 4.48:1 — a hair under AA for body text). Subtlety is achieved with size and weight hierarchy, not by washing text toward the background.
Common questions
Is 4.5:1 a legal requirement?
WCAG itself is a standard, not a law, but many laws and procurement rules point at WCAG 2.x AA — including regulations in the EU, US and elsewhere. Whether or not a lawyer is involved, AA is the level professional work is judged against.
Do links need to be distinguishable without colour alone?
Yes, in effect: body links that rely only on a colour change must also differ from surrounding text by at least 3:1 against that text, or carry another cue such as an underline. Underlining body links remains the simplest robust answer.
My checker gives a slightly different ratio than yours for the same colours. Who is right?
Differences of 0.01–0.05 usually come from rounding of channel values or from whether a colour was specified in a wider gamut and clamped first. If two reputable tools differ more than that, one of them was fed a different colour — check for alpha and for values copied from a gradient midpoint.
To wrap up
Contrast is the rare accessibility topic with a number at its centre: compute luminance honestly, compare against the right threshold for the size and job of the text, and fix failures by walking lightness while the hue stays home. Master that loop and the rest of accessible colour — states, graphics, dark surfaces — becomes variations on it.
Try it yourself
The contrast checker computes the ratio for any foreground/background pair and reports AA and AAA pass or fail for normal and large text, so the lightness walk described here takes seconds per step.