How to read a contrast ratio
A contrast ratio compares the relative luminance of two colors and runs from 1:1 for identical colors to 21:1 for black on white. Normal text needs 4.5:1 to meet WCAG AA and 7:1 for AAA. Large text and interface graphics need 3:1 and 4.5:1.
What the number is
Contrast ratio compares how much light two colors reflect, and nothing else. Each color
is reduced to a single value called relative luminance, and the ratio between them is
(lighter + 0.05) / (darker + 0.05). The 0.05 is there to account for
ambient light bouncing off a screen, which is why the scale tops out at 21:1 rather
than infinity.
Two things follow from that, and both surprise people. Hue is not part of the calculation at all, so red and green of the same lightness score the same as red on red. And the number is symmetric: light text on a dark background gives the same ratio as the reverse. Swapping them changes how it feels to read and does not change the ratio.
The five numbers worth knowing
There are only two levels and two text sizes, so there are four combinations, plus one rule that covers everything which is not text.
- 4.5:1 normal text, AA. The one that matters most and the one most palettes miss.
- 7:1 normal text, AAA.
- 3:1 large text, AA.
- 4.5:1 large text, AAA.
- 3:1 interface graphics, AA. Anything you need to see in order to use the thing.
Large text means 18.66px bold or 24px regular and above, which is 14pt bold or 18pt regular in the standard's own units. Note where that lands: the 16px or 17px that most interfaces call their body size is normal text, and so is nearly every heading below an h2. Large text is a narrower category than it sounds.
The graphics rule is the one that gets missed
The 3:1 requirement for interface graphics covers input borders, focus rings, icons, toggle states, chart lines, and the divider between two table rows if that divider is carrying meaning. None of it is text, so it never gets checked, and a page can have perfect body copy sitting inside a form whose boxes you cannot see.
Decorative borders are exempt, which is what makes this genuinely fiddly rather than just forgotten. A rule between two sections carries no information and can be as faint as you like. The border around a text input is what tells you where to click, so it is a user interface component and it needs 3:1. Same visual element, different requirement, depending on what it is doing.
Should you aim for AAA?
For long body copy, yes if you can. For everything else, usually not.
AA is what almost every legal requirement, procurement checklist and accessibility statement actually references. AAA at 7:1 is a genuinely high bar, and applying it to a whole palette tends to flatten a brand into black and gray, because very few brand colors reach 7:1 against anything except their own opposite. Treat AAA as a target for the text people read for minutes at a time and AA as the floor everywhere.
What the ratio does not tell you
Three things, and each one is a separate check.
It says nothing about hue. Two colors can sit at a comfortable 5:1 and be indistinguishable to someone with deuteranopia, because luminance is all the calculation looks at. If your interface uses red and green to mean failure and success, the ratio will report both as fine and both will be the same gray to a large number of people. That is what the color blindness simulator is for.
It says nothing about whether the text is readable. A ratio is not a typography check. Thin weights, tight letter spacing, small sizes and long line lengths all make text harder to read at exactly the same ratio. 21:1 hairline type at 11px is fully compliant and unpleasant.
It is a floor, not a goal. Passing every threshold means nothing in your design is disqualifying. It does not mean the design is good, and there is no score above AAA to chase.
Why one pair at a time stops working
Checking two colors is easy. The problem is that a design system has eight or nine, and every one of them can end up on every other one. Nine colors is 72 ordered pairs, so nobody checks them all, so the interesting failures ship: the accent on the tile, the muted text on the card, the link color on the one surface that got added last.
That is the case the palette contrast grid exists for. Paste the whole set, get every pair at once with its ratio and verdict. For a single pair, the contrast checker is faster and will also show you the nearest shade that passes when one fails.
The specific failure worth knowing about
There is one mistake common enough to deserve its own page: a brand accent that passes as a graphic and fails as text. It happens because accents are chosen for saturation, and saturation barely moves luminance. We shipped one ourselves and caught it by hand. That story, with the numbers, is here.