If your accessibility audit turned up color contrast errors, you're not alone. WebAIM's annual survey consistently finds low color contrast is the single most prevalent WCAG failure across the web. The good news: it's entirely fixable with a systematic approach.
This guide walks you through exactly what WCAG requires, how to measure contrast ratios, and how to update your CSS to pass every check.
See how 321 websites scored →
View the 2026 ReportColor contrast refers to the difference in luminance (perceived brightness) between foreground text and its background. People with low vision, color blindness, or age-related vision decline rely on sufficient contrast to read content.
WCAG 2.1 Criterion 1.4.3 (Contrast Minimum) requires a minimum ratio between text and its background. When that ratio falls below the threshold, your site fails the criterion — and real users struggle to read your content.
Beyond usability, contrast failures create legal exposure. ADA Title III lawsuits routinely cite WCAG 1.4.3 failures. Courts have found that contrast issues constitute barriers to access for blind and low-vision users.
| Text Type | WCAG AA Minimum | WCAG AAA Enhanced |
|---|---|---|
| Normal text (under 18pt / 14pt bold) | 4.5:1 | 7:1 |
| Large text (18pt+ or 14pt+ bold) | 3:1 | 4.5:1 |
| UI components and graphical objects | 3:1 | — |
| Inactive UI, decorative text, logos | Exempt | Exempt |
Most websites target WCAG AA, which is the legal standard referenced by the ADA and Section 508. WCAG AAA is aspirational but not legally required in most contexts.
Manual checking is impractical for any site with more than a handful of pages. Use an automated scanner first to get a complete picture.
Accessalyze scans every page on your site and flags every WCAG 1.4.3 failure with the exact failing ratio, the required ratio, and the specific element's CSS selector.
Scan Your Site Free →After running an automated scan, you'll have a list of failing elements with:
.nav-link, #sidebar p)WCAG uses relative luminance — a weighted average of RGB values that accounts for how humans perceive brightness. You don't need to memorize the formula, but understanding the concept helps you choose better colors.
The key insight: contrast is about relative difference, not absolute darkness. A medium gray on white may fail while the same gray on dark navy passes. The relationship between the two colors is what matters, not the colors in isolation.
For each failing element, you have two options: darken the text color, or lighten/darken the background. Usually darkening the text is simpler since backgrounds serve layout purposes.
/* Before — fails at 2.5:1 */
.body-text { color: #9ca3af; } /* Light gray on white */
/* After — passes at 9.7:1 */
.body-text { color: #374151; } /* Dark gray on white */
/* Before — #3b82f6 on white = 3.1:1 (fails for normal text) */
a { color: #3b82f6; }
/* After — #1d4ed8 on white = 7.2:1 (passes AA and AAA) */
a { color: #1d4ed8; }
/* Before — white on #60a5fa (light blue) = 2.4:1 (fails) */
.badge { background: #60a5fa; color: white; }
/* After — white on #1d4ed8 (dark blue) = 7.2:1 (passes) */
.badge { background: #1d4ed8; color: white; }
When text sits on a background image or gradient, the contrast must be evaluated at the worst-case point. Solutions include:
background: rgba(0,0,0,0.5);text-shadow: 0 1px 4px rgba(0,0,0,0.8);Placeholder text is notorious for failing contrast. Many browsers default to a very light gray. Fix it explicitly:
::placeholder { color: #6b7280; } /* 4.6:1 on white — just passes */
/* Even safer: */
::placeholder { color: #4b5563; } /* 7.2:1 on white — easily passes */
Disabled inputs, buttons, and form controls are exempt from the 4.5:1 requirement — WCAG explicitly carves them out. However, consider making them more visible anyway with opacity: 0.5 or similar, so all users can distinguish enabled from disabled states.
WCAG 2.2 introduced Criterion 2.4.11 (Focus Appearance) requiring focus rings to have 3:1 contrast against adjacent colors. Check that your :focus-visible styles meet this threshold too.
After updating your CSS, run a verification scan to confirm every flagged element now passes. Don't rely on visual inspection alone — the human eye is a poor judge of exact contrast ratios.
Fixing contrast once isn't enough if new designs keep introducing failures. Set up prevention mechanisms:
Define approved color combinations in your design system. Document which text colors are approved for which backgrounds. This keeps designers and developers from introducing ad-hoc colors that fail contrast.
Add accessibility linting to your CI pipeline using tools like axe-core, eslint-plugin-jsx-a11y, or Storybook's accessibility add-on. These catch many contrast issues before they reach production.
Set up a recurring automated scan to catch regressions introduced by ongoing development. Accessalyze can scan your site on a schedule and alert you to new failures.
| Foreground | Background | Ratio | Status |
|---|---|---|---|
| #9ca3af (gray-400) | #ffffff | 2.5:1 | Fail |
| #6b7280 (gray-500) | #ffffff | 4.6:1 | Pass AA |
| #3b82f6 (blue-500) | #ffffff | 3.1:1 | Fail |
| #1d4ed8 (blue-700) | #ffffff | 7.2:1 | Pass AA+ |
| #ffffff | #60a5fa (blue-400) | 2.4:1 | Fail |
| #ffffff | #1e40af (blue-800) | 9.1:1 | Pass AA+ |
| #ef4444 (red-500) | #ffffff | 3.9:1 | Fail |
| #b91c1c (red-700) | #ffffff | 7.0:1 | Pass AA+ |
If your site supports dark mode via prefers-color-scheme, you must verify contrast in both modes. A color pair that passes in light mode may fail in dark mode if you simply invert colors without checking.
Test dark mode explicitly during your scan. Accessalyze can test pages in both light and dark mode to catch these cross-mode failures.
Accessalyze scans your entire site, identifies every WCAG color contrast failure, and gives you the exact CSS values you need to fix them. Free to start — no credit card required.
Scan Your Site Free →Purely decorative images are exempt. But meaningful icons — like a search magnifying glass used without a text label — must meet the 3:1 UI component contrast requirement under WCAG 1.4.11 (Non-text Contrast).
You don't need to change your brand colors themselves, but you may need to use darker shades for text. Many brands have a full palette from light to dark — use the darker variants for text and the lighter ones for decorative backgrounds.
Yes, but the thresholds differ. Large text (18pt regular or 14pt bold) only needs 3:1, while smaller text needs 4.5:1. Visually prominent headings often pass even if body text doesn't.
Browser DevTools (Chrome and Firefox both have built-in contrast checkers), the WebAIM Contrast Checker, the Colour Contrast Analyser desktop app, and automated scanners like Accessalyze all work well. For production-scale checking across many pages, an automated scanner is the only practical option.
Try it yourself
Enter your website URL to get a free accessibility score.