InstantTools.org

← Blog

WCAG Contrast Ratios Explained: How to Actually Pass AA and AAA

September 12, 2026

Two colors can look like they contrast fine to your eye and still fail a formal accessibility check — because "readable to me, on my monitor, today" and "passes WCAG" are measuring different things. One is a subjective impression; the other is a specific mathematical formula applied to two exact color values.

The formula behind the pass/fail

WCAG 2.1 defines contrast using relative luminance — a calculated brightness value for a color derived from its red, green, and blue channels, weighted according to how the human eye perceives each color's contribution to overall brightness (green is weighted heaviest, blue the least, matching real perceptual sensitivity). The contrast ratio between two colors is then a specific ratio of their luminance values, defined in the spec, producing a single number: 1:1 for identical colors, up to 21:1 for pure black against pure white. WCAG Contrast Checker implements this exact luminance formula, not an approximation — the math matches the W3C specification precisely, which is what makes the resulting pass/fail meaningful rather than a rough estimate.

What AA and AAA actually require, and for what text

WCAG defines different minimum ratios depending on text size, because larger text is legible at lower contrast than small text is:

  • Normal text, AA: 4.5:1 minimum
  • Normal text, AAA: 7:1 minimum
  • Large text, AA: 3:1 minimum
  • Large text, AAA: 4.5:1 minimum
  • UI components and graphical objects, AA: 3:1 minimum

The tool checks your color pair against all five of these thresholds simultaneously and shows pass/fail on each — there's no toggle to switch between "normal text mode" and "large text mode"; all five results are visible at once, since which threshold actually applies to your situation depends on how you're using the colors (body copy vs. a large heading vs. a button border), not something the tool can know for you.

A detail that trips people up: hex only, no rgb() strings

The checker parses 3- or 6-digit hex color codes (#fff, #1a2b3c) — it does not parse an rgb(r, g, b) string directly. If your design system or CSS uses RGB notation, convert to hex first before pasting it in; this isn't a missing "nice to have," it's the actual input format the tool currently expects.

Where contrast problems actually show up

Two common sources of accidental contrast failures are worth knowing about specifically:

Gradients. A gradient that transitions from a light color to a dark one will have great contrast against text at one end and terrible contrast at the other — text placed anywhere across a gradient background needs to be checked against the worst point in that gradient, not just the average. If you're designing a gradient in CSS Gradient Generator with text overlaid on it, checking contrast at both extremes (and anywhere in between where text might sit) catches a failure that checking just one flat color would miss.

Colors baked into SVG icons or logos. An icon's fill color, if it's meant to convey information (not purely decorative) or sits directly against text, is subject to the same 3:1 UI-component threshold as any other interactive element. Running an SVG through SVG Optimizer to strip unnecessary metadata won't change its colors — optimization and accessibility are separate concerns — but it's a natural moment to also check the fill colors you're shipping, since you're already looking at the file.

The Bottom Line

Passing WCAG contrast isn't about a color "looking readable" — it's a specific luminance ratio calculated between two exact color values, checked against a threshold that depends on text size and context. Checking both ends of a gradient, using hex codes, and knowing which of the five thresholds actually applies to what you're designing turns "I think this is readable" into an answer you can actually defend in an accessibility review.

Tools Mentioned in This Guide