About WCAG Contrast
Contrast ratio measures the difference in perceived brightness between two colours, on a scale from 1:1 (no contrast โ grey on grey) to 21:1 (maximum โ black on white). The Web Content Accessibility Guidelines (WCAG), published by the W3C, define minimum ratios so that text stays readable regardless of vision, display quality or lighting conditions.
Contrast is the single most commonly failed accessibility check on the web. It affects roughly 1 in 12 men and 1 in 200 women with some form of colour blindness, everyone over 40 as the lens of the eye yellows, and anybody using a phone outdoors. Good contrast is not just a legal checkbox โ it is the difference between a design that works and one that doesn't.
WCAG 2.1 contrast requirements
| Level | Text size | Minimum ratio |
|---|---|---|
| AA | Normal (under 18pt / 24px) | 4.5:1 |
| AA | Large (18pt+ / 24px+, or 14pt+ bold) | 3:1 |
| AAA | Normal | 7:1 |
| AAA | Large | 4.5:1 |
| AA (non-text) | UI components, icons, form borders | 3:1 |
AA is the standard required by law in many jurisdictions (WCAG 2.1 AA is the current legal baseline for public-sector sites in the EU and US federal agencies). AAA is a stricter, aspirational target โ aim for it on essential content if you can, but don't let it block your whole design.
What counts as "large text"
WCAG defines large text by points, which map to CSS pixels at the usual 96 dpi:
- 18pt = 24px for regular weight
- 14pt = 18.66px for bold weight
In practice, most headings and hero copy qualify as large text and get the lower 3:1 / 4.5:1 thresholds. Body text, labels, captions and small print almost never qualify โ they need the full 4.5:1 AA or 7:1 AAA.
How the ratio is calculated
WCAG uses relative luminance, which is not the same as average RGB brightness. The formula weights the three channels according to how the human eye actually perceives them โ green contributes about 71% of perceived brightness, red about 21% and blue only about 7%. Then:
Contrast = (L1 + 0.05) / (L2 + 0.05)
where L1 is the lighter colour's luminance and L2 is the darker. The + 0.05 prevents division by zero for pure black. The result is always between 1:1 and 21:1, regardless of which colour is on top.
Beyond text: UI components and graphics
WCAG 2.1 added Success Criterion 1.4.11 (Non-text Contrast), which requires 3:1 for:
- Form input borders, focus rings and toggle states
- Icon buttons and interactive controls
- Chart lines, data markers and graph elements
- Any informational graphic where meaning depends on colour
This is why a subtle grey input border that "looks nice" may fail WCAG โ it needs to be visible against both the page background and any fill inside the input.
Tips for hitting contrast targets
- Adjust lightness, not hue. Keeping the hue and shifting lightness is the fastest way to fix a failing colour without wrecking your palette.
- Don't rely on greys. Many "nice" greys like
#888fail AA on white โ they look calm but read as low-contrast for anyone with imperfect vision. - Prefer dark text on light backgrounds. It is easier to reach 7:1 with near-black on a light tint than with light text on a dark tint.
- Add a second cue. Never rely on colour alone to signal meaning โ pair red/green with icons or labels.
- Test both light and dark modes. A colour that passes on white may fail on your dark theme's background.
Common use cases
Accessibility audits
Verify every text/background pair in your UI.
Building design systems
Test tokens before shipping them across an app.
Legal compliance
Meet WCAG 2.1 AA for public-sector or enterprise work.
Mobile readability
Check colours hold up on cheap screens and bright light.
Branding
Choose brand colours that work as real UI, not just swatches.
Data viz
Ensure chart lines and labels stay distinguishable.
Privacy and accuracy
This contrast checker runs entirely in your browser. All calculations happen locally in JavaScript using the WCAG relative-luminance formula. The colours you enter are never transmitted, stored or logged.