Color Contrast Checker

Check WCAG AA and AAA contrast ratio between foreground and background colors

Try an example

Foreground (text) color

Background color

Large Text Sample (18px bold)

Normal text sample β€” this is how your body text will appear against the background color you have chosen.

Contrast ratio

14.63:1

WCAG compliance

Pass

Normal AA

Pass

Normal AAA

Pass

Large AA

Pass

Large AAA

WCAG AA β€” Normal text: 4.5:1, Large text (18px+ or 14px bold): 3:1

WCAG AAA β€” Normal text: 7:1, Large text (18px+ or 14px bold): 4.5:1

What Is Color Contrast Checking?

Color contrast checking measures the luminance difference between a foreground color (typically text) and a background color, then expresses the result as a ratio. A ratio of 1:1 means the colors are identical; 21:1 is the maximum, representing black on white or vice versa. The Web Content Accessibility Guidelines (WCAG) published by the W3C define minimum contrast ratios that text must meet so that people with low vision or color deficiencies can read it.

The contrast ratio formula comes from WCAG 2.x and relies on relative luminance, a measure of how bright a color appears to the human eye. Relative luminance is calculated by linearizing each sRGB channel (removing gamma) and weighting the channels according to ITU-R BT.709 coefficients: 0.2126 for red, 0.7152 for green, and 0.0722 for blue. Green contributes the most because human eyes are most sensitive to green light. The ratio is then (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter color's luminance.

WCAG defines two conformance levels. Level AA requires a contrast ratio of at least 4.5:1 for normal-sized text and 3:1 for large text (18px or above, or 14px bold). Level AAA raises the bar to 7:1 and 4.5:1 respectively. WCAG 2.1 also introduced Success Criterion 1.4.11, which requires a 3:1 ratio for non-text UI components like borders, icons, and focus indicators.

Why Use This Contrast Checker?

Checking contrast by eye is unreliable. Colors that look distinct on your calibrated display may blur together on a low-quality laptop screen, under direct sunlight, or for someone with deuteranopia. A numeric ratio removes guesswork and gives you a pass/fail verdict against the WCAG standard.

⚑
Instant Ratio Calculation
Pick or type two colors and see the contrast ratio update in real time. No form to submit, no page reload.
πŸ”’
Privacy-first Processing
The luminance math runs entirely in your browser. No color values leave your machine, and no cookies or analytics track your choices.
🎯
AA and AAA Verdicts
Results show pass/fail status for WCAG AA and AAA, for both normal and large text sizes, so you know exactly which thresholds you meet.
πŸ“‹
No Account Required
Open the page and start testing. No sign-up, no rate limits. The tool works offline once the page has loaded.

Contrast Checker Use Cases

Frontend Development
Before shipping a UI change, paste the text color and background from your CSS into the checker to confirm the pair meets WCAG AA. This catches contrast failures before they reach code review or automated audits.
Design Handoff
Designers can verify that every color pair in a Figma file passes the required WCAG level before handing specs to engineers. Fixing contrast at the design stage is far cheaper than fixing it after implementation.
Accessibility Auditing
QA engineers running a WCAG audit can spot-check specific color combinations flagged by automated tools like Lighthouse or axe. The checker confirms the exact ratio and which levels pass or fail.
Design System Tokens
When defining color tokens for a design system, test each foreground/background pair to ensure the token palette meets AA at minimum. Document the ratios alongside the tokens so downstream teams trust the choices.
Email Template Testing
Email clients strip CSS features like opacity and blend modes, so the actual rendered colors may differ from your source. Test the final foreground and background values that reach the inbox to verify readability.
Studying Accessibility Standards
Students learning WCAG can experiment with different color pairs and immediately see how the ratio changes. Adjusting one channel at a time builds a working understanding of how luminance relates to perceived contrast.

WCAG Contrast Ratio Requirements

The table below summarizes the minimum contrast ratios required by WCAG 2.1 for different content types and conformance levels. Large text is defined as 18px (24 CSS pixels) or above at normal weight, or 14px (18.66 CSS pixels) or above at bold weight.

LevelMin ratioApplies toNote
AA Normal text4.5 : 1Body text, paragraphs, labelsMinimum for most UI text
AA Large text3.0 : 1Text >= 18px, or >= 14px boldMinimum for headings
AA UI components3.0 : 1Borders, icons, focus indicatorsNon-text contrast (WCAG 1.4.11)
AAA Normal text7.0 : 1Body text at highest standardEnhanced readability
AAA Large text4.5 : 1Large text at highest standardEnhanced for headings

Luminance, AA, and AAA Explained

The contrast ratio calculation has three stages: compute luminance for each color, derive the ratio, and compare it against WCAG thresholds.

Relative Luminance
A single number from 0 (black) to 1 (white) that represents how bright a color appears. It accounts for the non-linear sRGB gamma curve and the unequal sensitivity of the human eye to red, green, and blue. Pure green (#00FF00) has a luminance of 0.7152, while pure blue (#0000FF) has only 0.0722.
WCAG AA
The baseline accessibility level required by most legal standards, including the EU's European Accessibility Act (EAA) and Section 508 in the United States. AA demands a 4.5:1 ratio for normal text and 3:1 for large text. Most design systems target AA as the minimum for all text elements.
WCAG AAA
The enhanced level intended for content that must be readable by the widest possible audience, including users with significant vision impairment. AAA demands 7:1 for normal text and 4.5:1 for large text. Few entire sites achieve AAA across all pages, but critical content like legal notices and medical information often targets it.

Code Examples

Calculate WCAG contrast ratios programmatically. Each example implements the relative luminance formula from WCAG 2.x and the contrast ratio calculation. The same black-on-white and indigo-on-white pairs are tested for comparison.

JavaScript
// Calculate relative luminance per WCAG 2.x (sRGB)
function luminance(r, g, b) {
  const [rs, gs, bs] = [r, g, b].map(c => {
    c /= 255
    return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
  })
  return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs
}

// Contrast ratio between two RGB colors
function contrastRatio(fg, bg) {
  const l1 = luminance(...fg)
  const l2 = luminance(...bg)
  const lighter = Math.max(l1, l2)
  const darker  = Math.min(l1, l2)
  return (lighter + 0.05) / (darker + 0.05)
}

contrastRatio([0, 0, 0], [255, 255, 255])  // -> 21.0
contrastRatio([99, 102, 241], [255, 255, 255]) // -> 3.95
contrastRatio([29, 78, 216], [255, 255, 255])  // -> 6.06 (AA pass)
Python
def luminance(r: int, g: int, b: int) -> float:
    """Relative luminance per WCAG 2.x, ITU-R BT.709 coefficients."""
    channels = []
    for c in (r, g, b):
        c /= 255
        channels.append(c / 12.92 if c <= 0.04045 else ((c + 0.055) / 1.055) ** 2.4)
    return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2]

def contrast_ratio(fg: tuple, bg: tuple) -> float:
    l1 = luminance(*fg)
    l2 = luminance(*bg)
    lighter, darker = max(l1, l2), min(l1, l2)
    return (lighter + 0.05) / (darker + 0.05)

print(f"{contrast_ratio((0, 0, 0), (255, 255, 255)):.2f}")  # -> 21.00
print(f"{contrast_ratio((99, 102, 241), (255, 255, 255)):.2f}")  # -> 3.95

# Check WCAG AA for normal text
ratio = contrast_ratio((29, 78, 216), (255, 255, 255))
print(f"{ratio:.2f} β€” {'AA pass' if ratio >= 4.5 else 'AA fail'}")  # -> 6.06 β€” AA pass
Go
package main

import (
	"fmt"
	"math"
)

func linearize(c float64) float64 {
	c /= 255
	if c <= 0.04045 {
		return c / 12.92
	}
	return math.Pow((c+0.055)/1.055, 2.4)
}

func luminance(r, g, b int) float64 {
	return 0.2126*linearize(float64(r)) +
		0.7152*linearize(float64(g)) +
		0.0722*linearize(float64(b))
}

func contrastRatio(fgR, fgG, fgB, bgR, bgG, bgB int) float64 {
	l1 := luminance(fgR, fgG, fgB)
	l2 := luminance(bgR, bgG, bgB)
	lighter := math.Max(l1, l2)
	darker := math.Min(l1, l2)
	return (lighter + 0.05) / (darker + 0.05)
}

func main() {
	ratio := contrastRatio(0, 0, 0, 255, 255, 255)
	fmt.Printf("%.2f\n", ratio) // -> 21.00

	ratio = contrastRatio(29, 78, 216, 255, 255, 255)
	fmt.Printf("%.2f\n", ratio) // -> 6.06 (AA pass for normal text)
}
CSS
/* WCAG-safe color pairs β€” tested contrast ratios */

/* 12.63:1 β€” passes AAA normal text */
.high-contrast {
  color: #1e293b;          /* slate-800 */
  background: #f8fafc;     /* slate-50  */
}

/* 7.07:1 β€” passes AAA normal text */
.dark-theme-text {
  color: #e2e8f0;          /* slate-200 */
  background: #0f172a;     /* slate-900 */
}

/* 4.57:1 β€” passes AA normal, fails AAA */
.accent-on-white {
  color: #1d4ed8;          /* blue-700  */
  background: #ffffff;
}

/* 2.14:1 β€” fails AA for text, but passes 3:1 for large text */
.muted-heading {
  color: #94a3b8;          /* slate-400 */
  background: #ffffff;
}

Frequently Asked Questions

What is a good contrast ratio for text?
For body text on the web, aim for at least 4.5:1 (WCAG AA). Ratios above 7:1 meet WCAG AAA and are more comfortable for extended reading. Black on white yields the maximum ratio of 21:1, but a very dark gray (#1e293b) on white still gives around 12.6:1, which is well above AAA.
What counts as large text in WCAG?
WCAG defines large text as 18px (24 CSS pixels) at normal weight, or 14px (18.66 CSS pixels) at bold weight. Large text gets a lower contrast threshold because bigger letterforms are easier to perceive. In CSS, 1px equals 0.75pt, so 18pt equals 24px.
Is WCAG AA legally required?
In many jurisdictions, yes. The European Accessibility Act (EAA), which takes effect June 2025, references WCAG 2.1 AA. Section 508 of the US Rehabilitation Act requires federal agencies to meet WCAG 2.0 AA. The Americans with Disabilities Act (ADA) has been interpreted by US courts to require accessible websites, with WCAG AA as the standard. Canada, Australia, and the UK have similar mandates.
How is relative luminance calculated?
Each sRGB channel value (0-255) is divided by 255, then linearized: values at or below 0.04045 are divided by 12.92, and values above are transformed by ((c + 0.055) / 1.055) ^ 2.4. The three linearized channels are weighted by the ITU-R BT.709 coefficients (0.2126 R, 0.7152 G, 0.0722 B) and summed. The result is a number between 0 and 1.
Why does WCAG use a 0.05 offset in the contrast formula?
The 0.05 offset prevents division by zero when one of the colors is pure black (luminance = 0). It also accounts for ambient light and screen reflections that slightly raise the perceived luminance of even the darkest pixels. Without this offset, black on any dark color would produce an infinite or misleadingly high ratio.
Can two colors pass AA but still be hard to read?
Yes. WCAG contrast ratios measure luminance difference, not hue difference. A saturated red on saturated green can technically pass the ratio threshold while being uncomfortable to read for some viewers, especially those with red-green color vision deficiency. Pairing colors that differ in both luminance and hue tends to produce more comfortable results.
What is the difference between WCAG 2.x contrast and APCA?
WCAG 2.x uses a simple luminance ratio that treats foreground and background symmetrically. APCA (Advanced Perceptual Contrast Algorithm), proposed for WCAG 3.0, uses a perceptual lightness model that accounts for polarity: dark text on a light background has different perceived contrast than light text on a dark background at the same luminance difference. APCA is still a working draft and has not replaced the WCAG 2.x method in any regulation.