Color Contrast Checker
Test text and background color combinations against WCAG 2.1 AA and AAA accessibility standards.
WCAG 2.1 Contrast Requirements
The Web Content Accessibility Guidelines (WCAG) 2.1 define minimum contrast ratios to ensure text is readable by people with moderately low vision. Contrast ratio is expressed as a value between 1:1 (no contrast, identical colors) and 21:1 (maximum contrast, black on white). The requirements are organized into two conformance levels:
- AA (minimum) — 4.5:1 for normal text, 3:1 for large text
- AAA (enhanced) — 7:1 for normal text, 4.5:1 for large text
Large text is defined as 18pt (24px) regular weight or 14pt (18.66px) bold (font-weight 700 or greater). Non-text UI components and graphical objects require a minimum of 3:1 contrast against adjacent colors under WCAG 2.1 Success Criterion 1.4.11.
How Contrast Ratio Is Calculated
The contrast ratio formula uses the relative luminance of two colors. Relative luminance measures the perceived brightness of a color on a scale from 0 (black) to 1 (white), weighted according to human visual sensitivity to different wavelengths.
The calculation involves three steps:
// Step 1: Linearize RGB channels (remove gamma)
function linearize(channel) {
const c = channel / 255;
return c <= 0.04045
? c / 12.92
: Math.pow((c + 0.055) / 1.055, 2.4);
}
// Step 2: Calculate relative luminance
function luminance(r, g, b) {
const R = linearize(r);
const G = linearize(g);
const B = linearize(b);
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
}
// Step 3: Calculate contrast ratio
function contrastRatio(lum1, lum2) {
const lighter = Math.max(lum1, lum2);
const darker = Math.min(lum1, lum2);
return (lighter + 0.05) / (darker + 0.05);
}
The luminance coefficients (0.2126, 0.7152, 0.0722) reflect that the human eye is most sensitive to green light and least sensitive to blue. The gamma linearization step is critical because sRGB values are not linearly proportional to light intensity. Skipping this step produces incorrect contrast ratios.
Common Contrast Failures and Fixes
Many popular design patterns fail WCAG contrast requirements. Light gray placeholder text (#AAA on #FFF) has a ratio of only 2.32:1, far below the 4.5:1 minimum. Medium gray body text (#777 on #FFF) sits at 4.48:1, just barely failing AA. White text on brand-colored buttons often fails when the brand color is in the mid-lightness range.
To fix contrast issues without abandoning brand colors, use darker shades for text-bearing elements. For example, if your brand blue is #3B82F6 (which fails as text on white at 3.13:1), use #1D4ED8 (the 700 shade at 5.47:1) for text instead. Reserve the lighter shade for non-text elements like backgrounds, borders, or icons. The RGB to HSL converter can help you find darker shades by reducing the lightness value while keeping the same hue.
Testing Contrast in Your Workflow
Check contrast early in the design process, not as an afterthought. When building a color system, test every text-background combination in your Tailwind color palette or CSS variables against the WCAG thresholds. Automated tools catch the obvious failures, but also test with real content at actual font sizes since the large-text exception depends on rendered size, not just CSS values.
Frequently Asked Questions
What is the WCAG contrast ratio requirement?
WCAG 2.1 requires a minimum contrast ratio of 4.5:1 for normal text (AA level) and 7:1 for enhanced contrast (AAA level). Large text (18pt or 14pt bold and above) has relaxed requirements: 3:1 for AA and 4.5:1 for AAA. These ratios ensure text remains readable for people with low vision or color deficiencies.
How is contrast ratio calculated?
Contrast ratio is calculated as (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 computed from linearized RGB values using the formula L = 0.2126 * R + 0.7152 * G + 0.0722 * B, where each channel is linearized by applying a gamma correction curve.
What counts as large text in WCAG?
WCAG defines large text as 18 point (24px) or larger for regular weight, or 14 point (approximately 18.66px) or larger for bold weight (700+). Large text has more relaxed contrast requirements because the larger character size is inherently easier to read.
What are the most common contrast failures?
The most common failures are light gray text on white backgrounds (like #999 on #FFF at 2.85:1), placeholder text in input fields (often #AAA on #FFF at 2.32:1), and colored text on colored backgrounds where both have similar lightness values. Another frequent issue is white text on bright-colored buttons where the brand color is too light.
How do I fix low contrast without changing my brand colors?
You have several options: darken the background behind light text, use a darker shade of your brand color for text (e.g., use the 700 shade instead of 500), add a semi-transparent overlay behind text on images, increase font size to qualify for the relaxed large-text requirement, or use your brand color for non-text elements (borders, icons, backgrounds) while keeping text in a high-contrast neutral.
Related Tools
- Hex to RGB Converter — Convert color codes for contrast testing
- RGB to HSL Converter — Adjust lightness to fix contrast issues
- Tailwind CSS Color Reference — Find accessible color pairings in the Tailwind palette
Built by Michael Lip. 100% client-side.