Color Contrast Checker (WCAG) — Free Online Accessibility Tool
Check if your color combinations meet WCAG 2.1 accessibility standards. Calculate contrast ratios, preview text readability, simulate color blindness, and get suggestions for passing combinations. 100% client-side — no data leaves your browser.
What is a color contrast ratio? A contrast ratio compares the relative luminance of two colors
on a scale from 1:1 to 21:1, calculated as (L1 + 0.05) / (L2 + 0.05) where L1 is the lighter of the
two. WCAG 2.1 asks for at least 4.5:1 for body text, 3:1 for large text and
interface components, and 7:1 to reach level AAA on body text.
How to Use the Color Contrast Checker
-
Enter your two colors — Use the swatches or type hex values into the foreground and background fields. Three-digit shorthand such as
#0afis expanded automatically; anything that is not valid hex is ignored until it is. - Read the ratio — The large number is the contrast ratio between the two colors. It is symmetric — swapping foreground and background never changes it, so the Swap button is for checking how the pair reads, not the number.
- Check the four compliance badges — AA and AAA are evaluated separately for normal and large text, because a pair that fails for 16px body copy can still be legal for a 24px heading.
- Apply the suggested fix — When a threshold fails, the tool searches for the nearest passing color by moving the foreground's lightness in 0.5% steps while holding its hue and saturation, so the result still belongs to your palette.
- Preview real components — The sample area renders body text, large bold text, a solid button, an outline button, a badge and a link, which is where thin strokes and small labels usually give the pair away.
- Test the color-blindness views — Protanopia, deuteranopia, tritanopia and achromatopsia simulations show whether the pair still separates when hue information is reduced or missing.
How the Contrast Ratio Is Calculated
Contrast is not measured on the hex values you type. WCAG first converts each color to its relative
luminance — a single number from 0 for black to 1 for white that models how much light the color emits.
Each sRGB channel is divided by 255 and then linearized to undo the display gamma curve, using
c / 12.92 when the channel is at or below 0.03928 and ((c + 0.055) / 1.055)2.4
above it. The three linear channels are then weighted for the eye's sensitivity:
Green carries roughly seventy per cent of the weight and blue barely seven, which is why a saturated blue on black fails so often while a mid-green on black can pass. The two luminances are then compared, with the lighter color as L1:
ratio = (L1 + 0.05) / (L2 + 0.05)The 0.05 term represents ambient light reflecting off the screen, and it caps the scale: pure black against pure white gives (1.00 + 0.05) / (0.00 + 0.05) = 21, so 21:1 is the highest ratio any pair of sRGB colors can reach. The ratio is symmetric, so swapping foreground and background never changes the number — only how the pair looks. Everything here runs in JavaScript in your browser.
WCAG Success Criteria and Their Thresholds
| Criterion | Applies to | Minimum ratio |
|---|---|---|
| 1.4.3 Contrast (Minimum) — AA | Body text below 24px, or below 18.66px bold | 4.5:1 |
| 1.4.3 Contrast (Minimum) — AA | Large text: 24px and up, or 18.66px bold and up | 3:1 |
| 1.4.6 Contrast (Enhanced) — AAA | Body text | 7:1 |
| 1.4.6 Contrast (Enhanced) — AAA | Large text | 4.5:1 |
| 1.4.11 Non-text Contrast — AA | Control borders, icons, focus rings, chart marks | 3:1 |
"Large text" is 18pt (24px) or 14pt bold (18.66px) and above. The threshold drops because thicker strokes cover more pixels, so less luminance difference is needed to resolve the letterforms. Both 1.4.3 and 1.4.6 exempt incidental text, text inside a logotype, and text in a disabled control — but a disabled control that users are still expected to read is a usability problem regardless of what the criterion permits.
Reading the Number
| Ratio | What it means in practice |
|---|---|
| 1:1 | Identical luminance — the text is invisible even if the hues differ |
| Below 3:1 | Fails every text criterion; acceptable only for decorative or disabled elements |
| 3:1 | AA large text, and the floor for icons, borders and focus indicators |
| 4.5:1 | AA body text — the practical target for most interfaces |
| 7:1 | AAA body text; comfortable for users with moderately low vision |
| 21:1 | Pure black on pure white, the arithmetic maximum |
The ratio is a model, not a verdict. It ignores font weight below the large-text cut-off, stroke thickness, anti-aliasing, screen brightness and ambient light, and it is known to be harsh on light text over dark backgrounds and generous to mid-tone pairs. A perceptual replacement, APCA, is being developed for the draft WCAG 3 guidelines but is not part of any ratified standard, so 2.1 and 2.2 remain what conformance is measured against today. Treat a pass as a floor and check the preview with your own eyes.
Fixing a Color Pair That Fails
The fastest fix is almost always lightness, not hue. Because luminance is dominated by the green channel, nudging a color a few steps darker or lighter in HSL moves the ratio far more than rotating its hue, and it keeps the color recognizably part of your palette. That is exactly what the suggestion box does: it holds hue and saturation fixed and walks lightness in 0.5% steps until the target ratio is met, first downward and then upward.
- Move one color, not both. Changing the background usually affects more of the page than changing the text, so start with the text unless the background is the brand element.
- Increase weight before you increase size. Going from 400 to 600 thickens the strokes without changing layout, and 24px at any weight moves you into the 3:1 large-text bucket.
- Never rely on hue alone. Red and green error and success states look identical under deuteranopia — pair them with an icon, a label or a shape.
- Put a scrim behind text over photos. A semi-transparent black or white layer gives you a predictable background luminance instead of one that changes per image.
- Do not stop at pure black on white. 21:1 passes everything but produces noticeable halation for some readers; something like #1e293b on #f8fafc still clears AAA with less glare.
- Check the whole state machine. Hover, focus, visited, disabled and placeholder colors each need their own pass; placeholders and muted helper text are the most common failures on otherwise accessible pages.
Frequently Asked Questions
It is the ratio between the relative luminance of two colors, on a scale from 1:1 for identical luminance to 21:1 for black against white. WCAG uses it as a proxy for whether text can be resolved against its background. Because luminance ignores hue, two very different colors — a mid-red and a mid-green, say — can still produce a failing ratio.
Level AA is the level referenced by most accessibility regulations, including Section 508 in the United States and the European Accessibility Act, so 4.5:1 for body text is the usual working target. AAA is worth reaching for on long-form reading, error messages and form labels, but WCAG itself notes that AAA conformance is not achievable for all content.
Yes. WCAG treats text of 18pt (24px) or 14pt bold (18.66px) and larger as "large text" and drops the AA requirement from 4.5:1 to 3:1, and the AAA requirement from 7:1 to 4.5:1. Use the AA Large badge for headings and display type, and the AA Normal badge for anything at body size.
It is exact arithmetic on a simplified model. The formula assumes sRGB, an idealized gamma curve and a fixed ambient-light term, and it takes no account of stroke width, anti-aliasing, screen brightness or the surrounding page. Pairs near a threshold — 4.4:1 versus 4.6:1 — are effectively indistinguishable in practice, so use the preview rather than treating the boundary as physically meaningful.
It is an approximation. Each mode applies a fixed linear transform in linearized RGB to model dichromatic vision — protanopia, deuteranopia and tritanopia — plus a luminance-only conversion for achromatopsia. Real color vision deficiency is a spectrum, and anomalous trichromacy, the most common form, sits between normal vision and the simulated extreme. Use it to catch pairs that collapse, not to certify a design.
No. Hex parsing, luminance, the contrast ratio, the suggested fix and every simulation run in JavaScript on this page. Nothing is transmitted, stored or logged, and the tool works offline once the page has loaded.
Contrast ratio only covers the two colors you tested. Common culprits are a placeholder or helper text color you never checked, a hover or focus state with different colors, text sitting on a photograph where the effective background varies pixel to pixel, or a semi-transparent overlay that makes the rendered color different from the declared one. Test the composited color, not the source value.
Test the worst case. For a gradient or a photograph, sample the lightest and darkest points that sit under text and check both. For semi-transparent text, calculate the color after it is blended with what is behind it and enter that value — the ratio depends on what is actually painted, not on the color before compositing.
Use Cases
Signing Off a Design System Palette
Run every text-on-surface pair in a token set through the checker once, so component authors can pick colors later without re-testing each combination.
Porting a Light Theme to Dark Mode
Inverted palettes rarely keep their ratios. Re-check muted text, borders and disabled states against the dark surface before shipping the theme toggle.
Clearing an Accessibility Audit Finding
An automated scanner flags a failing pair with a ratio but no fix. Paste both colors here and take the suggested lightness adjustment straight into the stylesheet.
Public Sector Procurement Evidence
Teams answering a Section 508 or EN 301 549 questionnaire can record the exact ratio for each documented text pair instead of asserting compliance.
Charts and Data Visualization
Series colors, gridlines and axis labels fall under the 3:1 non-text rule. Check adjacent series against each other and against the plot background.