1.4.3 Contrast (Minimum)

WCAG 2.2 · 1.4.3 AA Perceivable

What it requires

The visual presentation of text and images of text must have a contrast ratio of at least 4.5:1 against its background. There are three exceptions:

  • Large text — at least 18 point, or 14 point bold (roughly 24 px, or 18.66 px bold) — needs only 3:1.
  • Incidental text — inactive (disabled) controls, pure decoration, text that is not visible to anyone, or text that is part of a picture containing other significant visual content — has no contrast requirement.
  • Logotypes — text that is part of a logo or brand name — has no requirement.

The ratio is measured from the relative luminance of the text colour and the background colour directly behind it, and ranges from 1:1 to 21:1.

Low text contrast is one of the most common and most felt barriers on the web. It affects:

  • People with low vision, who may not perceive faint text at all.
  • People with colour-vision deficiencies and reduced contrast sensitivity, including many older users as contrast sensitivity declines with age.
  • Anyone reading in bright sunlight, on a dimmed or low-quality screen, or under glare — a situational barrier that reaches every user.

How to detect it

Ways to check contrast
Check How Catches
Automated scan Run axe, Lighthouse, or WAVE on the page. Most solid-colour text/background pairs — good first pass.
Manual sampling Use a contrast checker / eyedropper on suspect text, especially text over gradients, images, or semi-transparent overlays. Cases tools skip or can't sample reliably.
States & themes Check hover, focus, visited, placeholder text, and every theme (light, dark, high contrast). Pairs that pass in one state/theme but fail in another.
Large-text rule Confirm anything tested at 3:1 truly meets the 18 pt / 14 pt-bold size. Body text wrongly judged against the relaxed threshold.

Automated tools catch a large share of failures but cannot judge text over imagery or confirm the size needed for the large-text exception, so pair them with manual checks.

How to fix it

  1. Identify each failing text/background pair from your audit.
  2. Adjust the foreground or background colour until the ratio reaches 4.5:1 (or 3:1 for qualifying large text) — usually darkening text or lightening its background.
  3. For text over images or gradients, add a solid or sufficiently opaque overlay, a text shadow, or a contained background plate so the effective ratio is met everywhere.
  4. Fix design tokens, not one-off pages, so the corrected pair applies site-wide and across every theme.
  5. Re-test all interactive states and themes after the change.
/* Body text: #595959 on #ffffff = 7:1 — passes AA (and AAA) */
.body-text { color: #595959; background: #ffffff; }

/* Large heading (24px+): #767676 on #ffffff = 4.54:1 — passes at 3:1 */
.lead { color: #767676; background: #ffffff; font-size: 1.5rem; }

Copy-paste tests

Automated coverage

The axe-core rule color-contrast flags failures of this criterion. Run it via the axe DevTools browser extension or axe-core in CI. Automated tools only catch some failures — they can't judge text over images or confirm the large-text size exception.

Run this in the browser console

contrast-suspects.js
// Read-only: lists text whose colour is faint relative to its background.
const lum = c => {
  const [r, g, b] = c.match(/\d+/g).map(n => {
    n /= 255; return n <= 0.03928 ? n / 12.92 : ((n + 0.055) / 1.055) ** 2.4;
  });
  return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
const rows = [];
document.querySelectorAll('body *').forEach(el => {
  if (!el.textContent.trim() || el.children.length) return;
  const s = getComputedStyle(el);
  const fg = lum(s.color), bg = lum(s.backgroundColor || 'rgb(255,255,255)');
  const ratio = (Math.max(fg, bg) + 0.05) / (Math.min(fg, bg) + 0.05);
  if (ratio < 4.5) { el.style.outline = '2px solid red'; rows.push({ el, ratio: ratio.toFixed(2), text: el.textContent.slice(0, 40) }); }
});
console.table(rows);

What to check manually: the script reads only the element's own background, so verify text sitting over images, gradients, or semi-transparent overlays with an eyedropper, and confirm any pair tested at 3:1 truly meets the 18 pt / 14 pt-bold large-text size.