← All GuidesAccessibility

WCAG Contrast Ratios Explained: A Practical Guide

The WCAG contrast ratio is one of those numbers that looks intimidating but is actually rooted in straightforward science. Here's what it means, where it comes from, and how to use it without fighting your design.

What the Ratio Actually Measures

Contrast ratio compares the relative luminance of two colors — not their perceived brightness, but a mathematically precise measure of how much light each color reflects. It runs from 1:1 (identical colors, no contrast at all) to 21:1 (black on white, maximum contrast).

Luminance weights the red, green, and blue channels differently because human eyes aren't equally sensitive to all wavelengths. Green contributes about 72% of perceived brightness, red around 21%, and blue just 7%. This is why a vivid blue text on a dark navy background can look clearly distinct to you while completely failing an automated contrast check — the luminance difference between those two blues is tiny even though your visual cortex is filling in the gap.

The Three Thresholds

WCAG 2.1 defines three minimum ratios, each tied to a specific use case:

  • 3:1 — Large text (18pt+, or 14pt bold) and non-text UI components: form input borders, focus rings, icon-only buttons. This threshold is also the minimum for Level AA on large text.
  • 4.5:1 — Normal body text, Level AA. This is the standard most teams target and the one that matters most in practice.
  • 7:1 — Level AAA. Required for critical interfaces — healthcare, government, financial dashboards. Demanding, but achievable with a thoughtful palette.

The 18pt rule in CSS: 18pt = 24px. 14pt bold ≈ 18.67px bold. Once you hit these sizes, you only need 3:1 for AA compliance — which opens up significantly more palette combinations for display headings.

Why 4.5:1? The Number Has a Reason

The 4.5:1 threshold wasn't pulled from thin air. It's derived from research on age-related vision loss: a person with 20/80 vision — roughly what many people in their 70s and 80s experience without correction — needs approximately 4.5× more contrast than someone with 20/20 vision to read the same text with equal clarity.

When you hit 4.5:1, your interface is usable for roughly 80–90% of the population, including people with moderate low vision. The jump to 7:1 (AAA) covers most people with severe low vision who aren't using screen readers as their primary assistive technology.

The Mistakes Designers Actually Make

Gray-on-white failure. The most common one. #999999 on white (#FFFFFF) passes the eyeball test on a calibrated studio monitor but lands at 2.85:1 — well below AA. At arm's length on a laptop in natural light, it's unreadable for a significant portion of your users. The fix is almost always to darken to #757575 or below (4.6:1 on white).

Purple-on-dark trap. Purple and dark navy are luminance siblings. Brand violet (#7B61FF) on a dark surface (#1A1A2E) often fails at 2.2:1 despite looking visually distinct. The eye is filling in contrast that isn't there in the data.

Hover and focus states. Many designs pass at their default state but fail in hover or disabled states where text lightens. Every interactive state needs its own contrast check.

Placeholder text. Input placeholder text (color: #999) almost universally fails on white backgrounds. WCAG 1.4.3 doesn't cover placeholders, but 1.4.6 (AAA) does — and practically speaking, illegible placeholder text increases form abandonment.

Fixing Failures Without Wrecking Your Design

Most contrast failures can be fixed with one of three moves:

  1. Darken, don't desaturate. Adding darkness to a brand color (shifting lightness in HSL) preserves its personality far better than graying it out. Take your brand accent and drop lightness by 10–20% — you'll often find a passing version that still reads as the same color family.
  2. Change the background, not the text. A white heading failing on a mid-tone card? Darken the card. Your text color is often non-negotiable; your surface color usually isn't.
  3. Use full-opacity text.rgba(255,255,255,0.6) on a dark background is a contrast failure waiting to happen. Use #fff and a darker surface instead of relying on opacity to create hierarchy.

A Note on Non-Text Contrast

WCAG 1.4.11 (Non-Text Contrast) requires 3:1 for UI components and graphical objects that convey information. This includes: the border of a text input, the checked state of a checkbox, a line in a chart, an icon in a navigation item. Most teams overlook this entirely and only check text — but a form with illegible borders fails WCAG just as definitively.

Check Your Color Pairs

Paste any two hex values and get AA/AAA pass/fail status, ratio, and a live preview — instantly.

Open Contrast Checker →