Color Contrast Checker Guide: WCAG Accessibility Standards
Technical Mastery Overview
What Is Color Contrast Ratio?
The WCAG contrast ratio is a measure of luminance difference between two colors, expressed as a ratio from 1:1 (identical) to 21:1 (black on white):
Contrast ratio = (L1 + 0.05) / (L2 + 0.05)
Where L1 is the relative luminance of the lighter color and L2 is the relative luminance of the darker color. Relative luminance is a linearized measure of perceived brightness.
Black: luminance = 0.0
White: luminance = 1.0
Black on white: (1.0 + 0.05) / (0.0 + 0.05) = 1.05 / 0.05 = 21:1
A ratio of 21:1 is the maximum. A ratio of 1:1 means the colors are identical — completely unreadable.
WCAG 2.1 Contrast Requirements
| Level | Normal text (< 18pt / < 14pt bold) | Large text (≥ 18pt / ≥ 14pt bold) | UI components |
|---|---|---|---|
| AA | 4.5:1 | 3:1 | 3:1 |
| AAA | 7:1 | 4.5:1 | — |
AA is the legal and practical baseline — required by ADA, EN 301 549 (EU), and most accessibility laws. AAA is the enhanced level, recommended for text-heavy content where maximum readability matters (legal documents, medical information, government sites).
Large text exception: 18pt regular (24px) or 14pt bold (approximately 19px bold) requires only 3:1 contrast. This reflects the fact that larger text is more readable at lower contrast.
Common Failing Color Combinations
These combinations feel "designed" but fail WCAG AA:
| Colors | Ratio | Status |
|---|---|---|
White #ffffff on light blue #90cdf4 |
1.9:1 | ❌ Fail |
Gray #6b7280 on white #ffffff |
4.4:1 | ❌ Fail (just under AA) |
Yellow #fbbf24 on white #ffffff |
1.7:1 | ❌ Fail |
Green #22c55e on white #ffffff |
1.7:1 | ❌ Fail |
Red #ef4444 on white #ffffff |
3.8:1 | ❌ Fail |
Blue #3b82f6 on white #ffffff |
3.4:1 | ❌ Fail |
Dark gray #374151 on white #ffffff |
10.7:1 | ✅ Pass AAA |
Almost black #111827 on white #ffffff |
18.1:1 | ✅ Pass AAA |
Many "brand blue" and "brand green" colors fail WCAG on white backgrounds at normal text size. The fix is either to darken the text color or lighten the background — not to remove the color entirely.
Fixing Failing Contrast Ratios
Darken the text color
/* Fails: blue text on white — 3.4:1 */
color: #3b82f6;
/* Passes AA: darker blue — 5.1:1 */
color: #1d4ed8;
/* Passes AAA: very dark blue — 8.0:1 */
color: #1e3a8a;
Use the color as an accent, not text
A brand blue that fails for text can still work for:
- Borders and dividers (not text-carrying)
- Background behind white text (if the combined ratio passes)
- Icons (large enough to be UI components, not text)
/* Blue text on white: fails (3.4:1) */
.button { color: #3b82f6; }
/* White text on blue background: passes AA (3.4:1 — wait, still fails) */
/* White on darker blue: passes */
.button {
background: #1d4ed8;
color: #ffffff; /* 5.1:1 — passes AA */
}
Don't rely on color alone
WCAG 1.4.1 requires that information conveyed by color also be conveyed by another means (shape, text, icon). An error field that turns red fails users with red-green color blindness if the only indicator is the color change. Add an icon or error text.
Color Blindness Considerations
About 8% of men have some form of color vision deficiency:
| Type | Prevalence | Cannot distinguish |
|---|---|---|
| Deuteranopia | 1% of men | Red and green |
| Protanopia | 1% of men | Red and green (different sensitivity) |
| Deuteranomaly | 5% of men | Red-green (weakened) |
| Tritanopia | Rare | Blue and yellow |
| Achromatopsia | Very rare | All color (sees only grayscale) |
High contrast helps all types — a well-chosen dark text on light background remains readable even in grayscale simulation. Test your palette by desaturating it completely and checking if all information is still clear.
Luminance Calculation Reference
function relativeLuminance(r, g, b) {
const toLinear = c => {
const s = c / 255;
return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
};
return 0.2126 * toLinear(r) + 0.7152 * toLinear(g) + 0.0722 * toLinear(b);
}
function contrastRatio(rgb1, rgb2) {
const l1 = relativeLuminance(...rgb1);
const l2 = relativeLuminance(...rgb2);
const [lighter, darker] = l1 > l2 ? [l1, l2] : [l2, l1];
return (lighter + 0.05) / (darker + 0.05);
}
Use our Color Converter to translate hex codes to RGB values before checking contrast, and our CSS Formatter to organize your color variable declarations after finalizing your accessible palette.
Accessibility Testing Workflow
- Define your color palette — primary, secondary, accent, neutral, semantic (error, warning, success)
- Test every text/background pair in this tool before writing CSS
- Test UI component states — default, hover, focus, disabled (all need 3:1 or 4.5:1)
- Test in context with simulated color blindness
- Test with actual screen readers — contrast alone doesn't cover all accessibility requirements
- Include in CI — tools like axe-core can run contrast checks automatically in your test suite
Use our HTML Formatter to audit the markup structure alongside color contrast checks — accessibility is both visual and structural.
Experience it now.
Use the professional-grade Contrast Checker with zero latency and 100% privacy in your browser.