The Complete Guide to WCAG Color Contrast
Updated 2026-07-11 · Reference information · Based on the WCAG 2.1/2.2 Recommendation.
1. Why contrast matters
Color contrast is the difference in perceived brightness between text (or a UI element) and its background. Low contrast makes content hard to read for everyone, and especially for people with low vision, color vision deficiency, or anyone using a screen in bright sunlight. The Web Content Accessibility Guidelines (WCAG) turn this into a measurable requirement: a numeric contrast ratio that must meet a threshold depending on the text size and conformance level.
2. The contrast ratio, step by step
WCAG 2.x defines contrast as a ratio between the relative luminance of two colors. There are three steps: linearize each channel, combine them into a luminance value, then form the ratio.
2.1 Linearize each sRGB channel
Screen colors are stored in the sRGB space, which is gamma-encoded. To measure perceived brightness you first convert each 8-bit channel (0–255) to a fraction c = channel / 255, then linearize:
- If
c ≤ 0.03928:c_linear = c / 12.92 - Otherwise:
c_linear = ((c + 0.055) / 1.055) ^ 2.4
2.2 Combine into relative luminance
The human eye is most sensitive to green and least to blue, so the linear channels are weighted with the Rec. 709 coefficients:
L = 0.2126 × R_linear + 0.7152 × G_linear + 0.0722 × B_linear
Pure black gives L = 0 and pure white gives L = 1.
2.3 Form the ratio
With the two luminance values, the contrast ratio is:
ratio = (L_lighter + 0.05) / (L_darker + 0.05)
The + 0.05 term models ambient light reflecting off the screen and keeps the ratio finite. The result ranges from 1:1 (identical colors) to 21:1 (black on white).
3. The thresholds: AA and AAA
WCAG defines two conformance levels for text contrast and one for non-text elements.
| Context | AA | AAA | SC |
|---|---|---|---|
| Normal text | 4.5:1 | 7:1 | 1.4.3 / 1.4.6 |
| Large text | 3:1 | 4.5:1 | 1.4.3 / 1.4.6 |
| UI & graphics | 3:1 | — | 1.4.11 |
A color combination passes a level when its ratio is greater than or equal to the threshold. So a measured 4.5:1 passes AA for normal text, and 6.9:1 does not reach AAA.
4. What is "large text"?
Large text has a relaxed requirement because bigger glyphs are legible at lower contrast. WCAG defines it as at least 18pt (roughly 24px) for regular weight, or at least 14pt (roughly 18.66px) when bold. Anything smaller is "normal text" and must meet the stricter 4.5:1 (AA) or 7:1 (AAA). Because pt-to-px depends on the platform, treat the px values as guidance and prefer the pt definition when in doubt.
5. Non-text contrast (SC 1.4.11)
Text is not the only thing users need to see. Success Criterion 1.4.11 requires a 3:1 ratio for the visual boundaries of active UI components (the border of an input, the outline of a button) and for meaningful graphical objects (icons, chart lines, focus indicators). There is no AAA level for non-text contrast, so 3:1 is the bar. This tool reports the UI column against that 3:1 threshold.
6. Fixing a failing combination
When a pair fails, you usually want the smallest visual change that passes. The most predictable move is to adjust lightness only, keeping the hue and saturation so the brand color still reads the same. If the background is light, darken the foreground; if the background is dark, lighten it. This tool does exactly that: it holds the foreground's hue and saturation and walks its HSL lightness until it reaches your target ratio, returning the closest passing color.
Sometimes lightness alone cannot get there — a saturated yellow can never reach 7:1 on white without becoming a different hue. In that case you must change the hue, reduce saturation, or change the background. The suggestion then falls back to whichever of black or white gives the most contrast, as a signal that the target is out of reach.
7. Practical tips
- Design to AA (4.5:1) as a baseline; reach for AAA (7:1) on body text where you can.
- Don't rely on color alone to convey meaning — pair it with text, icons, or patterns.
- Check hover, focus, disabled and placeholder states, not just the default one.
- Placeholder text is real text: it must also meet contrast requirements.
- Test the actual rendered colors, including any opacity, not the design-token values.