Skip to main content
Technique

Color Contrast Testing Guide

How to test and fix color contrast failures — covering WCAG 1.4.3 and 1.4.11 requirements, testing tools, manual procedures, and fixing contrast in CSS.

Understanding Color Contrast Requirements

WCAG defines two contrast-related criteria: 1.4.3 (Contrast Minimum, Level AA) covers text contrast, and 1.4.11 (Non-text Contrast, Level AA) covers UI components and graphical objects. Both require a minimum contrast ratio measured using the WCAG contrast formula, which compares the relative luminance of two colors on a scale from 1:1 (identical colors) to 21:1 (black on white).

The required ratios are:

  • Normal text (< 18pt or < 14pt bold): minimum 4.5:1 against its background.
  • Large text (≥ 18pt or ≥ 14pt bold): minimum 3:1 against its background.
  • UI components (borders of inputs, focus indicators, icons): minimum 3:1 against adjacent color(s).
  • Graphical objects (chart lines, diagram parts, icons): minimum 3:1.
  • Inactive/disabled components are exempt from contrast requirements.
  • Decorative text (text that is purely visual with no semantic meaning) is exempt.

Testing Tools

Use multiple tools because they catch different types of contrast failures:

  • axe DevTools (browser extension) — automated scan catches static text contrast failures. Free tier available.
  • Colour Contrast Analyser (TPGi) — desktop app that lets you pick colors from the screen with an eyedropper. Essential for testing gradients, images, and dynamic states. Free download at tpgi.com.
  • Chrome DevTools — in the Elements panel, click a color swatch to see the contrast ratio. The contrast checker shows a warning icon for failures.
  • Figma contrast plugins — A11y Annotation Kit, Contrast, or Color Blind plugins catch issues in design before development.
  • WebAIM Contrast Checker (webaim.org/resources/contrastchecker/) — paste hex codes to check ratios.
  • Lighthouse — includes contrast checks in its accessibility audit.

Manual Testing Procedure

  1. Run an automated scan with axe or Lighthouse and fix all flagged contrast failures first.
  2. Then manually test scenarios automated tools miss: hover states, focus states, active states, visited link colors, placeholder text, text on gradient backgrounds, text over images.
  3. Use the Colour Contrast Analyser eyedropper: hover the foreground text color, note the hex value. Hover the background color, note the hex value. Enter both into the tool and verify the ratio.
  4. Test all interactive states: default, hover, focus, active, disabled, visited, checked/unchecked.
  5. For text on images or gradients, identify the darkest and lightest background areas and test the worst-case contrast.
  6. Test in both light mode and dark mode if your site supports them.

Common Contrast Failures and Fixes

These are the most frequently occurring contrast failures in real-world audits:

/* Failure: light gray text on white (#767676 on #fff = 4.48:1, just below 4.5:1 requirement) */
.caption {
  color: #767676; /* fails for normal text */
  background: #fff;
}

/* Fix: darken the text color */
.caption {
  color: #696969; /* 4.72:1 — passes AA */
  background: #fff;
}
/* Failure: placeholder text too light */
input::placeholder {
  color: #aaa; /* #aaa on white = 2.32:1 — fails */
}

/* Fix: use a darker placeholder color */
input::placeholder {
  color: #767676; /* still light but passes AA for large text */
  /* OR */
  color: #6e6e6e; /* safer choice at 4.94:1 */
}
/* Failure: focus outline has insufficient contrast */
:focus {
  outline: 2px solid #a0c4ff; /* light blue on white = 2.1:1 — fails 1.4.11 */
}

/* Fix: use a darker focus color with sufficient contrast against both the
   focused element's background AND the surrounding page */
:focus-visible {
  outline: 3px solid #0057b7; /* #0057b7 on white = 5.66:1 — passes */
  outline-offset: 2px;
}
/* Failure: icon button with no text, icon color too light */
.icon-btn svg { fill: #c0c0c0; } /* #c0c0c0 on white = 1.61:1 — fails */

/* Fix: darken icon to meet 3:1 ratio for non-text */
.icon-btn svg { fill: #757575; } /* #757575 on white = 4.6:1 — passes */

/* Also: add accessible name to icon button! */
<button aria-label="Close dialog">
  <svg aria-hidden="true" focusable="false">...</svg>
</button>

Testing Dark Mode Contrast

Dark mode introduces its own contrast challenges. Text that had 7:1 contrast in light mode may have only 2:1 in dark mode if colors were simply inverted. Always test your dark mode palette independently:

@media (prefers-color-scheme: dark) {
  :root {
    --color-text: #e8e8e8;    /* on #1a1a1a bg = 10.5:1 — passes */
    --color-text-muted: #9e9e9e; /* on #1a1a1a bg = 3.85:1 — passes AA for large text, fails for normal */
    --color-primary: #60a5fa;   /* on #1a1a1a bg = 5.2:1 — passes */
  }
}

APCA: The Next Generation Contrast Standard

The Accessible Perceptual Contrast Algorithm (APCA) is the contrast algorithm proposed for WCAG 3.0. It is more perceptually accurate than the current WCAG 2.x formula, taking into account font weight and size, spatial frequency, and polarity. While WCAG 2.2 still uses the current algorithm, you can use the APCA Contrast Calculator (readtech.org/APCA) to supplement your testing and future-proof your color decisions.

Resources