What the 4.5:1 rule actually measures
Everyone knows the number. Far fewer know what it is computing, where it is wrong, and why passing it does not mean your text is readable.
↑ Click any of these to repaint the entire site with it.
The WCAG contrast requirement is the single most cited number in interface accessibility. It is also the one most often applied without anyone knowing what it does.
The formula#
ratio = (L1 + 0.05) / (L2 + 0.05)L1 and L2 are the relative luminances of the two colors, lighter first. Relative luminance is a weighted sum of the linear-light RGB channels:
L = 0.2126 R + 0.7152 G + 0.0722 BThree things to notice.
The weights are wildly uneven. Green contributes over seventy percent of perceived brightness; blue contributes seven. Change the blue channel of a color by fifty points and the contrast ratio barely moves. Change green by the same amount and it moves a lot.
The channels are linearised first. The 0–255 values in your hex code are gamma-encoded. Before they go into that sum they are converted back to linear light. This is why you cannot eyeball contrast from hex digits.
Hue is absent. There is no term for it. A saturated red and a saturated green at the same luminance have a contrast ratio of 1:1 — the formula says they are indistinguishable. For the purposes of text legibility that is nearly right, which surprises people, and it is exactly why "red text on green background" is a legibility problem and not only a color-blindness one.
The + 0.05 is a fudge for ambient screen reflection. It is also why the maximum possible ratio is 21:1 rather than infinity.
The thresholds#
| Requirement | Ratio | Applies to |
|---|---|---|
| AA normal text | 4.5:1 | under 18.66px bold or 24px regular |
| AA large text | 3:1 | 18.66px bold / 24px regular and up |
| AAA normal text | 7:1 | the same size boundary |
| AAA large text | 4.5:1 | |
| Non-text (UI, graphics) | 3:1 | borders, icons, focus rings, chart elements |
That last row gets skipped constantly. Your input borders, your focus indicators and your chart lines all need 3:1 against their background. A 1px hairline border at 1.3:1 is invisible to a lot of people and it is a failure, not a style.
Where the model is wrong#
WCAG 2.x contrast is known to be inaccurate, and this is not a fringe opinion — it is the stated reason WCAG 3 is replacing it.
It ignores polarity. Black on white and white on black both compute to 21:1. They do not read the same. Light text on a dark background blooms — the glyphs appear to thicken and bleed — which is why body copy in dark mode often needs to be a step lighter in weight or a step further in contrast than the same design in light mode. The formula cannot express this.
It is too lenient in the dark range. Two dark colors can clear 4.5:1 on paper and be genuinely hard to separate on a real screen in a bright room.
It is too harsh in the light range. Mid-tones on white frequently fail by a hair while being perfectly comfortable to read.
It knows nothing about font. 4.5:1 in a 300-weight geometric sans at 14px is not the same experience as 4.5:1 in a 500-weight grotesque at 16px. Contrast is necessary. It is not sufficient.
What to do about it#
Ship against the ratio. It is what gets audited, it is what appears in procurement requirements, and in several jurisdictions it is what appears in law. This is not the place to be clever.
But check APCA alongside it. APCA models polarity and gives you a value that maps to a specific size and weight rather than a single pass/fail line. When the two models disagree strongly, that disagreement is information — usually it means you have found one of the ranges where the WCAG formula is known to misbehave.
The habit worth building#
Do not check contrast at the end. Generate colors that pass in the first place.
If you know your background and you know you need 4.5:1, the lightness of your text is not a choice — it is solved for. Pick the hue, let the tool find the lightness, and you get a color that passes and sits as close to your background as it is allowed to, which keeps your hierarchy intact. Checking afterwards tends to produce a palette of colors that all sit at the extremes, because the fastest way to fix a failure is to reach for black.