Skip to main content

๐ŸŽจ Color Contrast Auditor

Detects and fixes color contrast violations using WCAG 2.1 guidelines and perceptual analysis. Expert in contrast ratio calculation, color blindness simulation, and providing accessible alternatives. Activate on "check contrast", "color accessibility", "WCAG audit", "readability check", "contrast ratio", "hard to read", "can't see text". NOT for general color theory (use color-theory-palette-harmony-expert), brand color selection (use web-design-expert), or non-visual accessibility (use ux-friction-analyzer).


Allowed Toolsโ€‹

Read, Write, Edit, WebFetch, Glob, Grep

Tagsโ€‹

accessibility wcag contrast color a11y visual-design

๐Ÿค Pairs Great Withโ€‹

Referencesโ€‹

Color Contrast Auditor

Detects color contrast violations that make text unreadable and provides WCAG-compliant fixes. Uses both mathematical contrast ratio analysis and perceptual evaluation via vision capabilities.

When to Useโ€‹

Activate on:

  • Screenshots of websites/apps with suspected contrast issues
  • CSS/Tailwind files for color audit
  • "I can't read this" or "this is hard to see"
  • Pre-launch accessibility checks
  • Design system color validation

NOT for:

  • Choosing brand colors (use web-design-expert)
  • Color harmony/aesthetics (use color-theory-palette-harmony-expert)
  • Non-visual accessibility (screen readers, keyboard nav)

WCAG 2.1 Contrast Requirementsโ€‹

Minimum Ratios (AA - Required)โ€‹

Text TypeMinimum RatioExample
Normal text (<24px, <18.66px bold)4.5:1Body copy, labels, buttons
Large text (โ‰ฅ24px or โ‰ฅ18.66px bold)3:1Headlines, hero text
UI components (borders, icons)3:1Form inputs, icons, focus rings
Graphical objects3:1Charts, infographics
Text TypeMinimum Ratio
Normal text7:1
Large text4.5:1

Non-Text Elementsโ€‹

ElementRequirement
Focus indicators3:1 against adjacent colors
Form field borders3:1 against background
Icons conveying meaning3:1 against background
Disabled elementsNo requirement (but consider UX)

Contrast Ratio Formulaโ€‹

Contrast Ratio = (L1 + 0.05) / (L2 + 0.05)

Where L1 = lighter color's relative luminance
L2 = darker color's relative luminance

Calculating Relative Luminanceโ€‹

function relativeLuminance(r, g, b) {
// Convert 0-255 to 0-1
let [rs, gs, bs] = [r, g, b].map(c => c / 255);

// Apply gamma correction
const gamma = c => c <= 0.03928
? c / 12.92
: Math.pow((c + 0.055) / 1.055, 2.4);

const [R, G, B] = [rs, gs, bs].map(gamma);

// Weighted sum (human eye sensitivity)
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
}

function contrastRatio(color1, color2) {
const l1 = relativeLuminance(...color1);
const l2 = relativeLuminance(...color2);
const lighter = Math.max(l1, l2);
const darker = Math.min(l1, l2);
return (lighter + 0.05) / (darker + 0.05);
}

Common Failing Patternsโ€‹

1. Light Text on Light Backgroundโ€‹

โŒ FAILING EXAMPLE (from user screenshot):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Background: #F5F2E8 (beige/cream) โ”‚
โ”‚ Text: #C8FF00 (lime green) โ”‚
โ”‚ โ”‚
โ”‚ "Scan. Crawl. Match. Report." โ”‚
โ”‚ โ† UNREADABLE โ”‚
โ”‚ โ”‚
โ”‚ Calculated Ratio: ~1.5:1 โ”‚
โ”‚ Required: 4.5:1 (normal) or 3:1 (large) โ”‚
โ”‚ Verdict: FAIL by 3x โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โœ… FIXED OPTIONS:
โ€ข Darken text to #5A7300 โ†’ Ratio: 4.5:1
โ€ข Darken background to #2A2A2A โ†’ Ratio: 12:1
โ€ข Use dark green #1A4D00 โ†’ Ratio: 8:1

2. Gray Text Syndromeโ€‹

โŒ COMMON FAILURE:
Background: #FFFFFF
Text: #AAAAAA (light gray)
Ratio: 2.3:1 โ† FAIL

โœ… FIXES:
โ€ข Text: #767676 โ†’ Ratio: 4.5:1 (minimum AA)
โ€ข Text: #595959 โ†’ Ratio: 7:1 (AAA)

3. Saturated Colors That Look Brightโ€‹

โŒ DECEPTIVE FAILURE:
Background: #FFF8E7 (warm white)
Text: #FF6B6B (coral/salmon)
Ratio: 2.8:1 โ† FAIL (looks "colorful" but fails)

โœ… FIXES:
โ€ข Text: #C62828 (darker red) โ†’ Ratio: 5.2:1
โ€ข Text: #8B0000 (dark red) โ†’ Ratio: 8.1:1

4. Trendy Low-Contrast Aestheticโ€‹

โŒ "MINIMALIST" FAILURE:
Background: #FAFAFA
Text: #E0E0E0
Ratio: 1.3:1 โ† SEVERELY FAILING

This is NOT minimalism. This is inaccessible.

โœ… MINIMALIST + ACCESSIBLE:
Background: #FAFAFA
Text: #616161 โ†’ Ratio: 5.7:1

5. Placeholder Text Too Lightโ€‹

โŒ COMMON FORM FAILURE:
Input background: #FFFFFF
Placeholder: #CCCCCC
Ratio: 1.6:1 โ† FAIL

โœ… FIX:
Placeholder: #757575 โ†’ Ratio: 4.6:1

6. Gradient Backgroundsโ€‹

โŒ VARIABLE CONTRAST:
Gradient: #FFFFFF โ†’ #000080
Text: #FFFFFF (fixed)

Top of gradient: 1:1 (invisible!)
Bottom of gradient: 8.6:1 (good)

โœ… SOLUTIONS:
โ€ข Add text shadow/outline
โ€ข Use semi-transparent overlay behind text
โ€ข Ensure ALL gradient stops pass contrast

Audit Methodologyโ€‹

Step 1: Visual Scan (Screenshot Analysis)โ€‹

When given a screenshot, identify:

  1. Text elements by size:

    • Headlines (large text โ†’ 3:1 required)
    • Body copy (normal text โ†’ 4.5:1 required)
    • UI labels (buttons, links โ†’ 4.5:1)
    • Captions/fine print (4.5:1 required)
  2. Interactive elements:

    • Button borders/backgrounds
    • Form field borders
    • Focus states
    • Icons with meaning
  3. Red flags to look for:

    • Light text on light backgrounds
    • Gray text on white
    • Colored text on colored backgrounds
    • Text over images without overlay

Step 2: Extract Colorsโ€‹

From CSS/code:

# Find all color declarations
grep -E "(color:|background:|#[0-9a-fA-F]{3,8}|rgb|hsl)" styles.css

From Tailwind:

# Find text/bg color classes
grep -E "(text-|bg-)" *.tsx *.jsx

Step 3: Calculate Ratiosโ€‹

For each text/background pair:

  1. Convert colors to RGB
  2. Calculate relative luminance
  3. Compute contrast ratio
  4. Compare to WCAG requirement

Step 4: Generate Reportโ€‹

# Contrast Audit Report

## Summary
- Total color pairs tested: X
- Passing (AA): Y
- Failing: Z
- Critical failures (&lt;2:1): N

## Failures by Severity

### Critical (Ratio &lt; 2:1)
| Location | Foreground | Background | Ratio | Required | Fix |
|----------|------------|------------|-------|----------|-----|
| Hero tagline | #C8FF00 | #F5F2E8 | 1.5:1 | 3:1 | #5A7300 |

### Moderate (Ratio 2:1 - 3:1)
...

### Minor (Ratio 3:1 - 4.5:1, normal text only)
...

## Recommended Fixes
[Specific color replacements with new ratios]

Color Blindness Considerationsโ€‹

Contrast requirements help but don't fully address color blindness. Additional checks:

Types to Considerโ€‹

TypeAffectedConsideration
Deuteranopia6% of malesRed/green confusion
Protanopia2% of malesRed appears dark
Tritanopia<1%Blue/yellow confusion

Best Practicesโ€‹

  1. Never rely on color alone for meaning

    • Add icons, patterns, or text labels
    • Red/green for error/success needs icons too
  2. Test problematic pairs:

    • Red + Green (stop/go)
    • Blue + Purple
    • Green + Brown
    • Light green + Yellow
  3. Use sufficient lightness difference

    • Even with same hue, different lightness helps

Quick Reference: Safe Color Pairsโ€‹

On White (#FFFFFF)โ€‹

Use CaseColorHexRatio
Body textDark gray#33333312.6:1
Secondary textMedium gray#7676764.5:1
LinksBlue#0066CC5.3:1
SuccessGreen#2E7D325.1:1
ErrorRed#C628286.0:1
WarningOrange-brown#E651004.5:1

On Black (#000000)โ€‹

Use CaseColorHexRatio
Body textLight gray#E0E0E013.4:1
SecondaryMedium gray#9E9E9E6.3:1
AccentLight blue#90CAF97.3:1

On Dark Gray (#1A1A1A)โ€‹

Use CaseColorHexRatio
Body textOff-white#F5F5F514.1:1
SecondaryLight gray#BDBDBD8.3:1

Tools & Validationโ€‹

Online Checkersโ€‹

Browser DevToolsโ€‹

// Chrome DevTools: Elements โ†’ Styles โ†’ hover color swatch
// Shows contrast ratio automatically

// Firefox: Accessibility Inspector
// Shows color contrast issues

Automated Testingโ€‹

// axe-core (popular a11y testing library)
const axe = require('axe-core');
axe.run(document, { rules: ['color-contrast'] });

// Lighthouse (built into Chrome)
// Performance โ†’ Accessibility โ†’ Color contrast

CLI Toolsโ€‹

# Lighthouse CLI
npx lighthouse https://example.com --only-categories=accessibility

# Pa11y
npx pa11y https://example.com

Integration with This Skillโ€‹

When analyzing a screenshot or codebase:

  1. I will identify all text/background color pairs
  2. I will calculate contrast ratios for each
  3. I will flag anything below WCAG AA thresholds
  4. I will suggest specific hex values that pass
  5. I will provide before/after comparisons

For the example screenshot (lime on beige):

AUDIT RESULT: CRITICAL FAILURE

Element: Hero tagline "Scan. Crawl. Match. Report."
Foreground: ~#C8FF00 (lime green)
Background: ~#F5F2E8 (beige)
Calculated Ratio: ~1.5:1
Required (large text): 3:1
Required (normal text): 4.5:1
Status: โŒ FAILS BY 2-3x

RECOMMENDED FIXES:
1. Darken text to #5A7300 (olive) โ†’ 4.8:1 โœ“
2. Darken text to #3D5C00 (dark olive) โ†’ 7.1:1 โœ“โœ“
3. Keep lime, darken BG to #3D3D3D โ†’ 8.2:1 โœ“โœ“
4. Use #1B5E20 (dark green) โ†’ 8.4:1 โœ“โœ“

Checklist for New Designsโ€‹

Before shipping:

  • All body text has โ‰ฅ4.5:1 contrast
  • All large text has โ‰ฅ3:1 contrast
  • All form borders have โ‰ฅ3:1 contrast
  • All icons conveying meaning have โ‰ฅ3:1 contrast
  • Placeholder text is readable (โ‰ฅ4.5:1)
  • Focus states are clearly visible (โ‰ฅ3:1)
  • Links are distinguishable without color alone
  • Error/success states use icons, not just color
  • Tested with color blindness simulators
  • Automated accessibility scan passes

Philosophy: Beautiful design and accessibility are not mutually exclusive. High contrast can be striking, dramatic, and intentional. Low contrast isn't "minimalist"โ€”it's exclusionary. Every unreadable word is a user lost.