Table of Contents
Color contrast is the single most impactful accessibility requirement you can implement. Poor contrast makes text unreadable for users with low vision, color blindness, or anyone in a bright environment on a mobile device. The Web Content Accessibility Guidelines (WCAG) define precise numerical thresholds for contrast — and unlike many accessibility requirements, these are both measurable and directly in your control as a designer or developer.
This guide explains the WCAG contrast requirements from first principles: how the contrast ratio is calculated, what the AA and AAA thresholds mean in practice, which UI elements each threshold applies to, how to test contrast efficiently during development, and how to fix contrast failures while preserving your visual design intent. It also covers WCAG 3.0's upcoming APCA model and explains when it matters.
How Contrast Ratio Is Calculated
The WCAG contrast ratio is defined as:
Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)
Where L1 is the relative luminance of the lighter color and L2 is the luminance of the darker color.
Relative luminance is computed from the linearized sRGB values of the color:
1. Normalize each channel: R/255, G/255, B/255
2. Linearize: if channel ≤ 0.04045, divide by 12.92
else ((channel + 0.055) / 1.055) ^ 2.4
3. Luminance L = 0.2126·R_lin + 0.7152·G_lin + 0.0722·B_linThe weighting (0.2126 / 0.7152 / 0.0722) reflects human eye sensitivity: green contributes the most to perceived brightness, blue the least.
Example: white on dark blue
- White (#FFFFFF): L = 1.0
- Dark blue (#1a3a5c): L ≈ 0.031
- Ratio = (1.0 + 0.05) / (0.031 + 0.05) = 1.05 / 0.081 ≈ 12.96:1 — passes easily
Example: grey on white
- Light grey (#BBBBBB): L ≈ 0.502
- White (#FFFFFF): L = 1.0
- Ratio = (1.0 + 0.05) / (0.502 + 0.05) = 1.05 / 0.552 ≈ 1.90:1 — fails all WCAG levels
The ratio ranges from 1:1 (identical colors, no contrast) to 21:1 (black on white, maximum contrast).
Check contrast ratio instantly— Shows WCAG AA and AAA pass/fail for any color pairWCAG 2.1 Contrast Requirements: AA vs AAA
WCAG 2.1 Success Criterion 1.4.3 (Minimum Contrast — Level AA) and 1.4.6 (Enhanced Contrast — Level AAA) define the required contrast ratios:
| Text Type | AA Required | AAA Required |
|---|---|---|
| Normal text (< 18pt or < 14pt bold) | 4.5:1 | 7:1 |
| Large text (≥ 18pt / ≥ 24px, or ≥ 14pt bold / ≥ 18.67px bold) | 3:1 | 4.5:1 |
| UI components & graphical objects | 3:1 | — |
| Decorative text, logos, disabled elements | None | None |
What is "large text"? WCAG defines large text as at least 18pt (24px) regular weight, or 14pt (approximately 18.67px) bold. The pixel values assume a screen resolution of 96 DPI. On high-DPI displays, browser zoom and device pixel ratio do not change the accessibility classification — WCAG measures at the reference pixel level.
Level AA is the standard legal and compliance target. It is required for US federal government websites (Section 508), the EU accessibility directive, and most accessibility audits. Most commercial software should target AA.
Level AAA is the aspirational standard. It is not required to "achieve WCAG" — the WCAG specification explicitly states that it is not possible to satisfy all AAA criteria for all content. Target AAA for body text in reading-intensive applications, medical or financial interfaces, and anywhere you serve users with significant visual impairment.
WCAG 2.2 (published October 2023) did not change contrast requirements. The updated criterion 1.4.11 (Non-text Contrast) still requires 3:1 for UI components.
What Counts as a UI Component (3:1 Ratio)
WCAG 2.1 Success Criterion 1.4.11 (Non-text Contrast) requires a 3:1 contrast ratio for UI components and graphical objects that convey information. This applies to:
- Form inputs: The visible boundary of a text input, checkbox, radio button, or select dropdown must have 3:1 contrast against its adjacent background.
- Buttons: The border or fill that defines the button boundary. A button with a transparent border that relies only on text color may fail if the button background does not contrast sufficiently with the page background.
- Focus indicators: The focus outline/ring must have 3:1 contrast against the adjacent colors.
- Icons that convey meaning: A checkmark icon in a success message, a warning triangle, an error X — if the icon communicates meaning without accompanying text, it needs 3:1 contrast.
- Charts and graphs: Data series in a chart must have 3:1 contrast against adjacent colors if color is the only way to distinguish them.
What is exempt:
- Inactive/disabled components (grey out and do not test for contrast)
- Purely decorative images and visual separators
- Logos and brand marks
Testing Contrast During Development
Method 1: Browser DevTools
Chrome DevTools, Firefox Inspector, and Edge DevTools all include a built-in contrast checker. Inspect any text element; click the color swatch in the Styles panel; the color picker shows the calculated contrast ratio, and a checkmark/warning indicates AA/AAA pass/fail.
Method 2: LevnTools WCAG Checker
Enter foreground and background colors in any format (hex, rgb, hsl) and get the ratio, AA/AAA result, and compliant alternative suggestions instantly — all client-side.
Method 3: Automated testing in CI
- axe-core (Deque) scans rendered DOM and flags contrast violations. Use
@axe-core/playwrightor@axe-core/cypressfor integration with E2E tests. - Lighthouse (Chrome DevTools, CI via
lighthouse-ci) includes a contrast audit under Accessibility. - jest-axe catches contrast failures in React component tests.
Method 4: Design phase (Figma)
Figma's built-in contrast checker (in the Inspect panel) shows ratio for selected text layers. The Figma plugin "Contrast" or "Able" provides batch-checking across frames.
Recommended workflow:
1. Set token-level contrast ratios during design system creation — guarantee compliance at the palette level, not element by element
2. Verify in Figma during design review
3. Automate in CI with axe-core to catch regressions
4. Spot-check tricky combinations (text over images, gradient backgrounds) manually
Check WCAG contrast ratio— AA and AAA results with suggestionsHow to Fix Contrast Failures Without Breaking Your Design
The most common mistake when fixing contrast is blindly darkening text or lightening backgrounds until the ratio passes — which often breaks the visual hierarchy or brand feel. A more systematic approach:
Step 1: Identify the exact failure.
Get the precise current ratio (e.g., 3.8:1 against a target of 4.5:1). This tells you how far you need to move.
Step 2: Adjust in HSL or OKLCH — not hex.
To increase contrast between text and background:
- If text is dark on light: decrease the text's HSL lightness (e.g., from 35% to 25%)
- If text is light on dark: increase the text's HSL lightness (e.g., from 65% to 78%)
- Only change one dimension (lightness) to preserve hue and saturation
Example fix:
/* Before: hsl(220, 70%, 55%) on white — ratio 2.9:1 (fail) */ color: hsl(220, 70%, 55%); /* After: hsl(220, 70%, 38%) on white — ratio 5.2:1 (AA pass) */ color: hsl(220, 70%, 38%);
Step 3: Consider background alternatives.
If darkening text would move it too far from the brand color, slightly darken the background instead:
/* Faint background makes text contrast viable */ background: hsl(220, 30%, 96%); /* was white */
Step 4: Use a darker-weight font.
Bolder text is classified as "large text" at a lower size threshold (14pt/18.67px bold vs 18pt/24px regular), which reduces the required ratio from 4.5:1 to 3:1.
Step 5: Increase font size.
Same logic — text ≥ 24px has the 3:1 large-text threshold.
APCA: The WCAG 3.0 Contrast Model
WCAG 3.0 (currently in draft, not yet published for compliance) uses a new contrast algorithm called APCA (Advanced Perceptual Contrast Algorithm), developed by the Accessible Perceptual Contrast project.
Why is APCA different from WCAG 2.x?
- WCAG 2.x luminance formula was designed for large plain text. APCA accounts for font size and weight — a 12px light-weight label has a different threshold than a 24px bold heading.
- APCA produces a signed "lightness contrast" value (Lc) ranging from roughly -110 to +110, where negative values indicate light text on dark background.
- APCA is context-sensitive: fluent reading text has stricter requirements than UI labels or placeholder text.
Should you use APCA now?
For most projects: no. WCAG 3.0 is not finalized and is not yet legally required anywhere. Use WCAG 2.1 AA (4.5:1) as your compliance target.
For cutting-edge design systems or internal tools: APCA provides more nuanced guidance, particularly for small text at various weights. You can explore the APCA model using the APCA contrast calculator (apca-w3.org).
Frequently Asked Questions
What contrast ratio do I need for WCAG AA compliance?
Does contrast apply to text over images or gradients?
Does WCAG contrast apply to placeholder text?
What about color blindness — is contrast enough?
Does contrast apply to icons with no text?
What is the minimum contrast for disabled UI elements?
Summary
Color contrast compliance is not a checkbox exercise — it is a fundamental part of building interfaces that work for everyone. The WCAG 4.5:1 threshold for AA compliance and 7:1 for AAA represent decades of research into human visual perception, and they apply whether your users have perfect vision, low vision, or are reading on a washed-out phone screen in sunlight.
Test contrast at the design system level — get your palette tokens right before writing component code — and automate it in CI to catch regressions. LevnTools' contrast checker gives you instant ratios and pass/fail results for any color pair, entirely in your browser.