Check WCAG Color Contrast Online: AA, AAA and Large Text

Check WCAG Color Contrast Online: AA, AAA and Large Text

Insufficient text-to-background contrast is the most common accessibility failure on the web. Check AA/AAA compliance by pasting two colors, no plugin or extension required.

13.09.2026
11 min read
Share this article:
accessibility
wcag
color-contrast
CSS
Tutorial

Contrast: the most common accessibility failure on the web

Every year, the WebAIM Million audit (an analysis of the most-visited home pages on the web) ranks insufficient text contrast as the top WCAG failure detected — ahead of missing alt text or unlabeled links. It's also one of the few accessibility criteria you can verify in seconds, without a screen reader or a full audit. The FastMinify contrast checker computes the WCAG 2.2 ratio between two CSS colors (HEX, RGB, HSL, OKLCH, color(), or named colors) and instantly shows AA/AAA verdicts for normal text, large text and non-text elements — without sending anything to a server. It goes beyond a single color pair: a matrix mode lets you cross an entire foreground palette against an entire background palette in one pass. The full cluster lives on the Color & CSS hub.

Live WCAG 2.2 verdicts — AA, AAA and non-text 3:1 (SC 1.4.11) for every color pair
Matrix mode up to 16 colors per axis — audit an entire design system palette in one pass
Opacity slider — check semi-transparent text composited against its real background
Experimental APCA overlay (WCAG 3 candidate) alongside the classic WCAG 2.2 ratio
Shareable URL — send the exact check to a designer or paste it into a PR
100% in the browser — no brand color ever leaves your tab

The contrast mistakes that come up again and again

The "elegant" light gray text on white

A #999999 gray on white gives a ratio of roughly 2.85:1 — well below the AA threshold of 4.5:1. Yet it's one of the most common design choices for secondary text, placeholders and captions.

Form placeholder text in a gray that's too light (often under 3:1)
Captions and metadata ("2h ago", "250 views") in pale gray on a light background
Copying a "neutral" gray from a Figma mockup without checking the actual ratio
Confusing "it reads fine on my screen" with a compliant ratio (brightness, calibration, eye fatigue all vary)
A brand-colored button that quietly fails

"Soft" brand colors (pastel blue, mint green, light orange) are often chosen for visual identity without ever being tested with white text on top.

Light blue primary button + white text: the ratio is sometimes under 3:1
A "disabled" state that visually looks like a poorly contrasted active state
Monochrome icons on a colored background without checking non-text contrast (3:1)
Testing only the default button state, never hover/focus/disabled
Text placed on an image with no scrim

A white headline works over the dark part of a hero photo's sky, but becomes unreadable over the bright part of a cloud — contrast varies depending on where the text sits on the image.

No dark gradient or overlay (scrim) under the text
Text tested only on the desktop crop of the image, never on the mobile crop
A light drop shadow used as the only guarantee of readability
A changing background image (carousel, user upload) with no guaranteed contrast
Visible focus removed to "clean things up"

outline: none with no replacement breaks keyboard navigation — and non-text contrast (SC 1.4.11) also applies to focus indicators, not just to text.

`outline: none` with no alternative focus ring
A custom focus ring that's too pale against the background (often under 3:1)
Visible focus tested only in light mode, forgotten in dark mode
No contrast check on form field borders

AA, AAA and large text: which ratio should you target?

Normal text: AA (4.5:1) or AAA (7:1)?

WCAG 1.4.3 (Contrast Minimum) requires a ratio of at least 4.5:1 for normal text at level AA. The stricter AAA level (criterion 1.4.6) raises the bar to 7:1. AA is the level targeted by nearly every legal accessibility requirement (Section 508/ADA in the US, EN 301 549 in Europe, RGAA in France); AAA remains recommended but is rarely mandated site-wide.

AA (4.5:1): the legal floor in most accessibility regulations
AAA (7:1): recommended for critical content (payment forms, medical/legal content)
A ratio of 21:1 (pure black on pure white) is the theoretical maximum — there's no point going higher
A ratio that looks fine at a glance (e.g. 4.2:1) can fail AA by a hair — always check the exact number, not the visual impression
Large text: the threshold drops to 3:1 (AA) / 4.5:1 (AAA)

WCAG defines "large text" as text at least 24px (18pt), or at least 18.67px (14pt) when bold (weight ≥ 700). Below those thresholds, text counts as normal even if it looks visually imposing. FastMinify automatically computes which threshold applies based on the size and weight you enter.

≥ 24px, any weight: large text → AA = 3:1, AAA = 4.5:1
≥ 18.67px AND weight ≥ 700 (bold): large text → same reduced thresholds
17px bold does NOT count as large text — a common trap
A 40px H1 benefits from the reduced threshold; a 12px bold badge never does
Non-text contrast (SC 1.4.11): 3:1 for the interface

Since WCAG 2.1, criterion 1.4.11 (Non-text Contrast) requires a ratio of at least 3:1 for UI components (form field borders, checkboxes, meaningful icons, focus indicators) against their adjacent color — not just for text.

Unfocused form field border: 3:1 minimum against the page background
Focus ring (outline/box-shadow): 3:1 minimum against both the background AND the element
Purely decorative icons (carrying no information) are exempt from this criterion
The FastMinify checker shows this verdict separately — a pair can pass non-text while failing normal-text contrast

How the contrast ratio is actually calculated

The WCAG formula: relative luminance, not just a hue difference

The WCAG 2.x ratio compares the relative luminance of the two colors (a value from 0 to 1 derived from linearized RGB channels, weighted 0.2126 for red, 0.7152 for green, 0.0722 for blue — the human eye perceives green far more intensely than blue). The final ratio is (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter color's luminance. That's why two colors that look "clearly different" can end up with a close ratio, while two hues that look similar can have very different luminances.

Before

color: #999999; background: #ffffff; /* Ratio ≈ 2.85:1 → fails AA (normal text) */

After

color: #595959; background: #ffffff; /* Ratio ≈ 7.0:1 → passes AAA (normal text) */
Result ranges from 1:1 (identical colors) to 21:1 (pure black / pure white)
Green carries more weight than blue in the formula — a bright blue on white often fails sooner than a green of similar perceived brightness
The formula ignores perceived hue — only luminance matters for the classic WCAG ratio
FastMinify accepts HEX, RGB, HSL, OKLCH and color() as input and converts them to sRGB before computing (via colorjs.io)
APCA, the WCAG 3 candidate (experimental preview)

The WCAG 2.x ratio has a known limitation: it treats "black on white" and "white on black" symmetrically, which doesn't always match real perception. APCA (Advanced Perceptual Contrast Algorithm), a candidate for WCAG 3, accounts for polarity (light text on dark background vs. the reverse) and font size for a finer-grained judgment. FastMinify offers an optional APCA overlay alongside the official WCAG 2.2 ratio — not as a replacement, since WCAG 3 isn't a published standard yet.

APCA returns an "Lc" (Lightness Contrast) score rather than a classic ratio
Polarity (normal or reversed) affects the score — the same color pair doesn't have the same Lc depending on which is foreground and which is background
As of today, only the WCAG 2.2 ratio (AA/AAA) counts for legal compliance (Section 508, ADA, EN 301 549, RGAA)
Useful for anticipating a future move to WCAG 3, not for a current compliance audit

color-contrast-checker workflow: from a color pair to a full palette

Check a color pair in seconds

Open the contrast checker, paste your foreground and background color in any CSS format (HEX, RGB, HSL, OKLCH, named). The ratio and the AA/AAA/non-text badges update live. Adjust text size and weight to see the "large text" threshold kick in automatically.

1

Step 1 — Paste both colors

Foreground and background, in any valid CSS format. No manual conversion needed.

2

Step 2 — Set text size and weight

16px/400 by default (normal text). Switch to 24px or 18.67px+bold to test a heading — the "large text" threshold (3:1/4.5:1) applies automatically.

3

Step 3 — Read the verdict

Exact ratio (e.g. 4.87:1), AA/AAA/AA-large/fail badge for text, and a separate verdict for non-text contrast (3:1, SC 1.4.11).

Scenario — auditing a button and its disabled state

A primary button usually has three color variants (normal, hover, disabled) that often go untested individually.

Test the button text on the "normal" background — aim for at least AA (4.5:1)
Test the same pair on the "hover" state — the color often changes, and so does the ratio
Test the "disabled" state separately — a low ratio is acceptable there if the state is genuinely non-interactive and announced as such (aria-disabled)
Check the button border (if visible) against the page background — that's non-text contrast, 3:1 threshold
Matrix mode: audit an entire palette at once

Instead of testing a design system's combinations one by one, paste your list of text colors as rows and your list of background colors as columns (up to 16 colors per axis). The result shows a grid with a verdict for every intersection, filterable by conformance level (AAA / AA / AA-large / fail).

Useful for validating every color token in a design system in a single pass
Filter by level: quickly isolate only the combinations that fail
Catches "borderline" pairs (e.g. 4.4:1, just under the AA threshold) that a manual pair-by-pair check would easily miss
Works with the same color formats as pair mode (you can mix HEX/RGB/HSL within a single list)
Share a check with your team

Every check (colors, text size, matrix or pair mode, APCA options) is encoded into the URL. Copy the link from the address bar and paste it into a pull request, a ticket, or a message to your designer — the page reopens in exactly the same state.

No data stored server-side — the entire state lives in URL parameters
Handy for documenting a contrast failure found during review
The link stays valid indefinitely as long as the tool is online

Making contrast a CI gate, not just a design back-and-forth

Automate detection with axe-core or Lighthouse CI

A manual checker is perfect for designing a palette; to prevent regressions, contrast should also be verified automatically on every pull request. axe-core and Lighthouse CI catch most contrast failures on static text (they struggle more with text over images or gradients).

Basic example

// axe-core with Playwright — fails the test on insufficient contrast import { test, expect } from '@playwright/test' import AxeBuilder from '@axe-core/playwright' test('no contrast regression', async ({ page }) => { await page.goto('/') const results = await new AxeBuilder({ page }) .withTags(['wcag2aa']) .analyze() const contrastIssues = results.violations.filter( (v) => v.id === 'color-contrast' ) expect(contrastIssues).toEqual([]) })
FastMinify color-contrast-checker

Fast manual checks, no install, no data sent anywhere. The matrix mode, unique among these options, lets you audit a whole design system in a single pass, and the shareable URL makes design/dev collaboration easy. Trade-off: it's a manual check that doesn't replace an automated CI audit, and it doesn't detect contrast on an image or a complex gradient.

Browser DevTools (Chrome/Firefox)

The built-in color picker shows the contrast ratio directly on the selected element on the live page, with computed styles — no external tool needed. Trade-off: one element at a time, which gets tedious across a full palette, with no matrix mode or link sharing.

axe-core / Lighthouse CI

An automated audit built into the CI pipeline systematically catches contrast regressions on every pull request, and covers accessibility beyond just contrast. Trade-off: it doesn't replace the upfront palette design phase, and can produce false negatives on text overlaid on an image.

Conclusion

Color contrast remains the most common accessibility failure on the web — and one of the easiest to fix once detected. AA (4.5:1) for normal text, 3:1 for large text and non-text elements: three numbers worth remembering before shipping a palette. The FastMinify contrast checker gives you the verdict instantly, in pair mode or matrix mode for an entire design system, without ever sending your brand colors to a server. Pair it with an axe-core audit in CI to prevent regressions, and with the rest of the Color & CSS hub to build a consistent palette end to end.

Target AA (4.5:1) for normal text, 3:1 for large text and non-text elements (borders, focus, icons)
Test every state of an interactive component — normal, hover, focus, disabled — not just the default
Use matrix mode to validate an entire design system rather than pair by pair
Add axe-core or Lighthouse CI to your pipeline to prevent contrast regressions after shipping
The WCAG 2.2 ratio is what counts legally today — treat APCA as a preview of the future, not a compliance reference
Share this article
Share this article: