WCAG Color Contrast Requirements: AA vs AAA Explained

♿ Accessibility⏱️ 7 min readFree checker included

Contrast is the most-failed WCAG success criterion in audits, and the cheapest to fix — if you know the numbers. Here are the thresholds, what they measure, why near-misses are so common, and how to repair a failing palette without redesigning anything.

Advertisement

What are the actual WCAG contrast numbers?

Two tiers, five thresholds:

CriterionTierApplies toMinimum ratio
1.4.3 Contrast (Minimum)AANormal text4.5:1
1.4.3 Contrast (Minimum)AALarge text3:1
1.4.6 Contrast (Enhanced)AAANormal text7:1
1.4.6 Contrast (Enhanced)AAALarge text4.5:1
1.4.11 Non-text ContrastAAIcons, borders, focus rings3:1

AA is the tier that laws and procurement contracts point at — Section 508 in the US and EN 301 549 in the EU both reference it. AAA is an enhanced target nobody is required to hit, though it's a sensible goal for long-form reading surfaces and anything aimed at low-vision users.

What counts as "large text"?

18 point regular weight — 24 CSS pixels — or 14 point bold, which is roughly 18.7px. Bigger glyphs survive lower contrast because more pixels carry the shape, so the ratio requirement relaxes from 4.5:1 to 3:1. Everything below those sizes is normal text at the stricter ratio, which is why body copy is where audits find failures: 16px body text in a mid-gray fails while the 32px heading next to it passes.

What does the ratio actually measure?

Not perceived brightness — a weighted, linearized luminance. Each sRGB channel gets expanded (c/12.92 below 0.04045, ((c+0.055)/1.055)^2.4 above), the three channels combine as 0.2126R + 0.7152G + 0.0722B, and the ratio is the lighter luminance plus 0.05 divided by the darker plus 0.05. The offsets keep the scale finite: identical colors give 1:1, black on white tops out at 21:1.

The gamma expansion is why eyeballing fails. A gray that "looks about halfway" between black and white is far brighter, luminance-wise, than the midpoint suggests — so palettes that look balanced measure unbalanced.

Why do near-misses dominate failure reports?

Because the pass line lands between adjacent hex values. The lightest gray that passes AA on white is #767676 at 4.54:1; one step lighter, #777777, measures 4.48:1 and fails. Two hundredths of a ratio separate a compliant design system from a failed audit, and no monitor renders that difference visibly. Grays aren't special — brand colors sit just as close to the line: Tailwind's blue-600 passes body text on white at 5.17:1, while green-600 (3.30:1) only works for large text or icons.

The practical rule: never adopt a text color because it "looks readable." Measure it, and keep a margin — aiming for 4.6:1 rather than 4.5:1 means a rounding change in a build won't silently flip a verdict.

Does contrast apply to buttons, icons, and placeholders?

Yes, through 1.4.11 Non-text Contrast: icons, input borders, focus indicators, checkbox marks, and chart lines need 3:1 against adjacent colors so users can see the thing they're meant to operate. Placeholder text, despite its ghost styling, is real text and must meet 4.5:1 — the pale-gray placeholder is one of the most common single-element failures on the web.

Exemptions are narrow: logotypes, purely decorative elements, and text incidentally captured inside images (a street sign in a photo) don't need to meet anything.

How do you fix a failing pair?

Move the text color toward the far endpoint — darken it on light backgrounds, lighten it on dark ones — in the smallest step that clears the threshold. On white, that usually means #777777 → #767676; for a saturated brand color it means shifting one shade darker in the same family (amber-500 on white fails at 2.15:1, but the same amber on black passes AAA at 9.78:1, so background choice is a lever too). The color contrast checker does this arithmetic for you: it finds the nearest shade that passes and shows the exact ratio for every tier, which turns a palette argument into a one-click fix.

What about gradients, images, and dark mode?

Check your palette now

Paste any two hex values into the Color Contrast Checker for the exact ratio, AA/AAA verdicts on all tiers, and the nearest passing shade if you miss. To build the palette in the first place, grab values with the Color Picker or lift them straight from a design screenshot with the Image Color Picker, then convert formats in the Color Converter.

Test a color pair in two seconds

Exact WCAG ratio, five verdict chips, and a fix-it button that finds the nearest passing shade. Free, no upload.

Check contrast →

The bottom line

Four numbers cover almost every decision — 4.5:1 body, 3:1 large text and UI, 7:1 if you're chasing AAA. Measure instead of eyeballing, because the pass line sits between adjacent hex values, and fix failures by nudging the text color the smallest distance that clears the bar. Keep the evidence: a shareable result URL is the difference between "we fixed it" and "we can prove we fixed it."

Advertisement