Skip to main content
Perceivable WCAG 1.4.3 84% fail

Color Contrast

Text must meet a 4.5:1 contrast ratio against its background (3:1 for large text ≥18pt/14pt bold). The single most common WCAG failure — found on 84% of homepages in the 2026 WebAIM Million.

In plain terms

If text is too faint against its background, people with low vision — and anyone reading in bright sunlight — can't make it out. The colors need enough difference to stand apart.

Contrast checker Try different combinations
Aa
The quick brown fox jumps over the lazy dog
2.6:1
ratio
Fail
AA normal text (4.5:1)
Fail
AA large text (3:1)

WCAG 1.4.3 requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text (18pt / 14pt bold). WCAG 1.4.6 (Level AAA) raises this to 7:1 and 4.5:1 respectively.

Common failure patterns include: gray placeholder text, light-colored footer links, text overlaid on photographs without a scrim, disabled button states with insufficient contrast, and branded colors chosen for aesthetics over readability.

Tools: Chrome DevTools color picker (shows ratio), Contrast Checker browser extensions, Figma plugins (Stark, A11y - Color Contrast Checker).

Why this matters

This fails on 84% of homepages — the single most detected WCAG failure for 7 consecutive years. It directly impacts 253M+ people with vision impairments, 300M with color vision deficiency, and everyone reading screens in bright environments or aging eyes.

How to detect

Quick check

Run axe DevTools or WAVE on your page for automated checks. Then manually inspect: placeholder text, disabled buttons, footer links, text over images, and any text using opacity or rgba colors. Check both light and dark mode.

How to fix

:root {
  --text-primary: #09090b;   /* 18:1 on white */
  --text-secondary: #52525b; /* 7.4:1 */
  --text-muted: #71717a;     /* 4.7:1 — minimum for normal text */
}

/* Text over images needs a reliable overlay */
.hero-overlay {
  background: linear-gradient(rgba(0,0,0,0.55), rgba(0,0,0,0.55));
}

/* Never rely on opacity for text */
.bad  { color: rgba(0,0,0,0.4); } /* ✗ unpredictable ratio */
.good { color: #71717a; }          /* ✓ testable, reliable */