WCAG Contrast Checker

Real-time color contrast checker for WCAG 2.1 AA / AAA and APCA — paste any two colors, see the ratio, the verdict, a live preview at every text size, color-blindness simulations, and the nearest passing colors when you fail. 100% in your browser.

What it does

Instant ratio with full WCAG verdict

Paste any two colors and see the WCAG 2.1 contrast ratio (to 2 decimal places) plus pass/fail badges for every threshold the spec defines: AA Normal (4.5:1), AA Large (3:1), AAA Normal (7:1), AAA Large (4.5:1), and Non-text / UI Components (3:1). No need to remember which threshold applies where — every applicable verdict appears at once.

APCA score alongside WCAG 2.1

Every check also runs APCA — the Advanced Perceptual Contrast Algorithm being developed for WCAG 3.0 — and reports the Lc score with body-text, large-text, and fluent-reading thresholds. Use APCA as a forward-looking cross-check on edge cases where WCAG 2.1 marginally passes but the design feels low-contrast.

Live preview, every size and weight

Sample text renders in your two colors at 12 / 14 / 16 / 18 / 24 / 32 pixels in regular and bold weights — exactly the sizes that determine "normal" vs "large" text under WCAG. Real component previews (button, link, alert, form input) show how the colors behave in actual UI, not abstract swatches.

Color blindness simulation

Four simulations sit alongside the preview — protanopia (red-blind), deuteranopia (green-blind), tritanopia (blue-blind), and achromatopsia (full color blindness). Daltonization matrices are applied client-side so you can spot pairs that pass contrast but fail to differentiate under common color vision deficiencies.

Automatic suggestions when you fail

When a pair fails any threshold, the Suggestions panel walks the HSL lightness axis from your starting color and reports the nearest passing hex in each direction — for both the foreground and the background, at both AA and AAA targets. You get a usable replacement in one click.

Permalink and export

Every state is encoded in the URL (`?fg=…&bg=…`) so you can paste the link into a design review and have the recipient see exactly what you saw. Export as CSS variables, SCSS, Tailwind class hints, or W3C design tokens. Copy any value with a single click.

How to use WCAG Contrast Checker

  1. 1
    Enter two colors

    Type a hex code (`#0066cc`), an `rgb()` value, an `hsl()` value, or a CSS named color (`crimson`, `darkgray`) into the foreground and background fields. The native color picker is available next to each field for visual selection.

  2. 2
    Read the ratio and verdict

    The ratio appears immediately — for example, `5.41:1`. Below it, five badges show pass/fail for AA Normal, AA Large, AAA Normal, AAA Large, and UI Components. APCA Lc is reported alongside.

  3. 3
    Inspect the preview and color-blindness panels

    Scan the live text preview at every WCAG-relevant font size. Check the four color-blindness simulations to confirm the pair is distinguishable beyond luminance contrast.

  4. 4
    If a pair fails, accept a suggestion

    The Suggestions panel proposes the nearest passing colors for AA and AAA, in both directions (lighter and darker). Click any suggestion to replace your foreground or background.

  5. 5
    Copy or share the result

    Use the Export panel to copy the colors as CSS variables, SCSS, Tailwind class hints, or W3C design tokens. Click "Share" to copy a permalink that encodes both colors — paste it into a design review or Slack thread.

When to use this

Designer auditing a brand palette

You inherit a brand color system and need to know which pairs are accessible for body text. Paste each combination in turn, watch the AA badges, and use the Suggestions panel to find the nearest accessible variant when a pair fails.

Frontend engineer wiring a design system

You’re defining `--color-text-primary` and `--color-text-secondary` against a `--color-surface-default`. Test each token pair against AA — and flag any that only pass for large text in your design tokens metadata.

Accessibility reviewer auditing a PR

A design changes a button color. Paste the new color and the surrounding surface; share the permalink in the PR review with the verdict and APCA score so the team can decide whether to ship.

Compliance team writing an accessibility statement

Document the WCAG conformance level your product targets (AA is typical) and reference the contrast checker results for primary palette pairs as evidence in your VPAT / ACR.

Common errors & fixes

Hex input shows "Invalid color"
Hex codes must be 3, 6, or 8 characters (after the `#`), composed only of `0–9` and `a–f`. The 8-character variant includes alpha — the checker drops alpha because contrast is computed on opaque colors.
rgba()/hsla() with alpha gives unexpected results
WCAG contrast is defined on opaque colors. The checker ignores the alpha channel — to model semi-transparent overlays, manually composite the foreground over the background first (e.g., `mix(white, blue, 50%)`) and check the resulting opaque hex.
My pair passes AA but the preview still feels low-contrast
WCAG 2.1’s formula is known to over-credit pairs in certain hue regions (saturated mid-tones, dark mode). Check the APCA Lc score — if it’s below 75, the pair will read as low-contrast in practice even if WCAG 2.1 marginally passes.
Two pairs have the same contrast ratio but look different
Identical luminance ratios can map to different perceptual contrasts depending on hue, saturation, and polarity (dark-on-light vs light-on-dark). APCA models this and will return different Lc scores. Use APCA as the tiebreaker.

Technical details

WCAG versionWCAG 2.1 (current); APCA shown alongside as WCAG 3.0 candidate
Ratio formula(L1 + 0.05) / (L2 + 0.05), where L = 0.2126R + 0.7152G + 0.0722B (linearized)
Large-text threshold18pt (≈24px) regular, or 14pt (≈18.66px) bold
Accepted color formatshex (3/6/8), rgb()/rgba(), hsl()/hsla(), 147 CSS named colors
APCA constantsBoW 0.56/0.57, WoB 0.65/0.62, soft-clip 0.022, scale 1.14
Color blindness modelBrettel/Viénot/Mollon daltonization matrices
Privacy100% client-side; no analytics on color choices, no upload

Why 4.5:1, and where the number came from

The 4.5:1 threshold for AA body text is anchored in research on the impact of low vision (around 20/40 acuity, common after age 50) on text readability. The original target was 7:1 — the AAA threshold today — but the working group introduced AA at 4.5:1 to give organizations a more achievable bar.

The asymmetric +0.05 added to both luminances in the ratio formula handles the fact that real-world black is never perfectly black on a screen — there’s always some ambient reflection. Without the offset, dividing by zero would break for true black on black.

What WCAG 2.1 gets wrong, and why APCA exists

The WCAG 2.1 ratio is symmetric — black-on-white scores identically to white-on-black. Human perception isn’t. Dark text on a light background is easier to read at the same luminance ratio because of how the visual system adapts to surrounding brightness.

The formula also overweights green relative to perceptual reality and produces unintuitive results for saturated colors. APCA — the Advanced Perceptual Contrast Algorithm — corrects all of this with polarity-aware coefficients, a different gamma curve, and soft-clipping for very dark colors. It’s the candidate algorithm for WCAG 3.0, and most accessibility researchers consider it the better measure today. WCAG 2.1 remains the legal standard, however, so this checker shows both.

Beyond contrast: what passing AA does not tell you

Contrast is necessary but not sufficient. A pair that passes AA can still be inaccessible because of color confusability under color blindness, font weight too thin to register at the rendered size, line-height too tight to scan, or contrast that fails in dark mode while passing in light. The color-blindness simulation panel here addresses one dimension; the live preview addresses another. The full picture requires considering reading flow, semantics (don’t convey meaning with color alone), and context (will this be read in sunlight?). Ratio passes are table stakes, not the finish line.

Frequently Asked Questions

Is this checker accurate?

Yes — it implements the WCAG 2.1 luminance formula exactly as specified and produces ratios identical to WebAIM’s reference checker to two decimal places. APCA implementation matches the published reference values. Cross-check any pair you’re uncertain about against WebAIM at https://webaim.org/resources/contrastchecker/.

What contrast ratio do I need?

For WCAG 2.1 Level AA — the standard most organizations target — body text needs **4.5:1** and large text (18pt+ regular or 14pt+ bold) needs **3:1**. UI components and graphical objects need **3:1** under SC 1.4.11. AAA tightens body text to 7:1 and large text to 4.5:1. Logos and inactive components are exempt.

What counts as "large text"?

**18 point regular** (about 24 CSS pixels) or **14 point bold** (about 18.66 CSS pixels), measured at the rendered size on the user’s viewport. Tailwind `text-lg` (18px) is **not** large under WCAG. The font weight matters — bold relaxes the threshold because bold strokes carry more pixel mass per glyph.

Why is APCA different from WCAG 2.1?

WCAG 2.1’s formula is symmetric and ignores polarity, which doesn’t match how human vision actually perceives contrast. APCA uses polarity-aware coefficients (different math for dark-on-light vs light-on-dark), a different gamma curve, and soft-clipping for very dark colors. It produces a perceptual Lc score from -108 to +106 instead of a ratio. APCA is the candidate algorithm for WCAG 3.0.

Does my logo need to meet WCAG contrast?

No — WCAG explicitly exempts logos and brand wordmarks (the "logotype" exception). The intent is to avoid forcing brand redesigns purely for compliance. Everything around the logo (taglines, navigation, captions, body copy) still must meet the standard for your conformance level.

How do I check focus-ring contrast?

Focus rings fall under SC 1.4.11 (Non-text Contrast) and require **3:1** against the surrounding background. Trigger focus on the element, sample the ring color, and check it against the lower-contrast surface adjacent to the focused element. WCAG 2.2’s SC 2.4.13 (Focus Appearance) is even stricter — at least 2 CSS pixels thick AND 3:1 contrast against both inner and outer surfaces.

What about dark mode?

WCAG applies identically to dark mode — the same ratios, same large-text rules. But APCA is *especially* useful for dark mode, where WCAG 2.1’s symmetric formula often disagrees with perception. A pair that scores 4.5:1 against pure black may read as significantly less contrasty than the same ratio against white.

Can I check transparent or semi-transparent colors?

WCAG contrast is defined for opaque colors. To check a semi-transparent overlay, manually composite the overlay color onto its background first (using sRGB averaging or your browser’s `color-mix()`), then check the resulting opaque hex against the next layer.

Why do two pairs with the same ratio look different?

Identical WCAG 2.1 ratios can map to different perceived contrast because the formula doesn’t account for hue, polarity, or saturation. A 4.5:1 pair of saturated mid-tones often reads as lower contrast than a 4.5:1 pair of neutrals at the same ratio. APCA captures this difference and is a better predictor of real readability.

How does the suggestion engine work?

When a pair fails, the engine walks the HSL **lightness** axis from your starting color in both directions (lighter and darker). It returns the first color along each direction that meets the target ratio against the other color. The result preserves hue and saturation as much as possible — so suggestions feel like adjusted versions of your color rather than completely different ones.

Is the tool itself accessible?

Yes — the tool meets WCAG AAA on its own UI. Every control is keyboard-reachable with a visible focus ring; every input has an accessible label; the live preview is announced to screen readers when colors change. The whole point of an accessibility tool is for it to model the standard it teaches.

Where does the data go?

Nowhere. All calculations run in your browser. There’s no upload, no API call, no analytics on the colors you check. The permalink encodes both colors in the URL itself — no server storage, no account, no tracking. Close the tab and the state is gone unless you saved the link.

Related Tools