Last updated
What Is WCAG Contrast?
WCAG (Web Content Accessibility Guidelines) defines minimum contrast ratios between text and background colors to ensure readability for users with low vision or color blindness. The WCAG Contrast Checker calculates the contrast ratio and shows whether your color combination passes Level AA (minimum) or Level AAA (enhanced) requirements.
WCAG Contrast Requirements
Level AA (minimum — required by most accessibility laws):
Normal text (< 18pt or < 14pt bold): 4.5:1 minimum
Large text (≥ 18pt or ≥ 14pt bold): 3:1 minimum
UI components and graphics: 3:1 minimum
Level AAA (enhanced):
Normal text: 7:1 minimum
Large text: 4.5:1 minimum
Contrast ratio scale:
1:1 — identical colors (no contrast)
21:1 — black on white (maximum contrast)
Common Color Combinations — Pass/Fail
Foreground Background Ratio AA Normal AA Large AAA
---------- ---------- ----- --------- -------- ---
#000000 #FFFFFF 21:1 ✓ Pass ✓ Pass ✓ Pass
#333333 #FFFFFF 12.6:1 ✓ Pass ✓ Pass ✓ Pass
#767676 #FFFFFF 4.54:1 ✓ Pass ✓ Pass ✗ Fail
#949494 #FFFFFF 2.85:1 ✗ Fail ✗ Fail ✗ Fail
#FFFFFF #0066CC 4.56:1 ✓ Pass ✓ Pass ✗ Fail
#FFFFFF #3B82F6 3.0:1 ✗ Fail ✓ Pass ✗ Fail
#1E40AF #DBEAFE 7.2:1 ✓ Pass ✓ Pass ✓ Pass
#FF0000 #FFFFFF 3.99:1 ✗ Fail ✓ Pass ✗ Fail
#CC0000 #FFFFFF 5.74:1 ✓ Pass ✓ Pass ✗ Fail
Contrast Ratio Calculation
Formula: ratio = (L1 + 0.05) / (L2 + 0.05)
where L1 = relative luminance of lighter color
L2 = relative luminance of darker color
Relative luminance calculation for #336699:
R = 51/255 = 0.2
G = 102/255 = 0.4
B = 153/255 = 0.6
Linearize each channel:
R_lin = 0.2/12.92 = 0.0155 (if ≤ 0.04045)
G_lin = ((0.4 + 0.055)/1.055)^2.4 = 0.1329
B_lin = ((0.6 + 0.055)/1.055)^2.4 = 0.3185
L = 0.2126 × R_lin + 0.7152 × G_lin + 0.0722 × B_lin
L = 0.2126 × 0.0155 + 0.7152 × 0.1329 + 0.0722 × 0.3185
L = 0.003295 + 0.095059 + 0.022996 = 0.121
Contrast with white (#FFFFFF, L=1.0):
ratio = (1.0 + 0.05) / (0.121 + 0.05) = 1.05 / 0.171 = 6.14:1
→ Passes AA ✓, Fails AAA ✗
Large Text Definition
Text qualifies as "large" (lower contrast requirement) when:
≥ 18pt (24px) at normal weight
≥ 14pt (approximately 18.67px) at bold weight
CSS examples:
font-size: 24px; → large text (18pt)
font-size: 1.5rem; → large text (if root = 16px)
font-size: 18px; font-weight: bold; → large text (14pt bold)
font-size: 16px; font-weight: bold; → normal text (< 14pt bold)
font-size: 14px; → normal text
Fixing Failing Contrast
Problem: Light gray text on white background
Foreground: #AAAAAA
Background: #FFFFFF
Ratio: 2.32:1 — FAILS AA ✗
Fix option 1 — darken the text:
#767676 on #FFFFFF = 4.54:1 ✓ (barely passes AA)
#595959 on #FFFFFF = 7.0:1 ✓ (passes AAA)
Fix option 2 — darken the background:
#AAAAAA on #404040 = 4.6:1 ✓ (passes AA)
Fix option 3 — use a colored combination:
#1E40AF on #EFF6FF = 8.1:1 ✓ (passes AAA)
---
Problem: White text on light blue button
Foreground: #FFFFFF
Background: #60A5FA (Tailwind blue-400)
Ratio: 2.5:1 — FAILS AA ✗
Fix: Use darker blue
#FFFFFF on #1D4ED8 (blue-700) = 7.2:1 ✓ (passes AAA)
Accessible Color Palette Examples
Dark text on light backgrounds (AA+):
#1A1A1A on #FFFFFF = 19.6:1 ✓✓✓
#374151 on #F9FAFB = 11.5:1 ✓✓✓
#1E40AF on #EFF6FF = 8.1:1 ✓✓✓
#065F46 on #ECFDF5 = 8.4:1 ✓✓✓
#7C2D12 on #FFF7ED = 8.9:1 ✓✓✓
Light text on dark backgrounds (AA+):
#FFFFFF on #1F2937 = 16.1:1 ✓✓✓
#F9FAFB on #111827 = 18.1:1 ✓✓✓
#DBEAFE on #1E3A8A = 7.5:1 ✓✓✓
Checking Contrast in Code
// JavaScript — WCAG contrast ratio calculator
function getLuminance(hex) {
const rgb = parseInt(hex.slice(1), 16);
const r = (rgb >> 16) / 255;
const g = ((rgb >> 8) & 0xff) / 255;
const b = (rgb & 0xff) / 255;
const linearize = c => c <= 0.04045
? c / 12.92
: Math.pow((c + 0.055) / 1.055, 2.4);
return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
}
function contrastRatio(hex1, hex2) {
const l1 = getLuminance(hex1);
const l2 = getLuminance(hex2);
const lighter = Math.max(l1, l2);
const darker = Math.min(l1, l2);
return (lighter + 0.05) / (darker + 0.05);
}
const ratio = contrastRatio('#336699', '#FFFFFF');
console.log(ratio.toFixed(2)); // 6.14
console.log(ratio >= 4.5 ? 'AA Pass' : 'AA Fail'); // AA Pass
Common Accessibility Mistakes
- Light gray placeholder text on white inputs (often fails AA)
- White text on medium-blue buttons (often fails AA)
- Yellow text on white backgrounds (almost always fails)
- Light text on light image backgrounds (unpredictable contrast)
- Relying on color alone to convey information (color blindness issue)
- Disabled state text with insufficient contrast (still needs 3:1 for UI components)