sfw/fix
color-contrast high

Insufficient text color contrast (WCAG 1.4.3)

Text-to-background contrast falls below 4.5:1 (or 3:1 for large text), failing the axe-core color-contrast check.

What you see

Elements must meet minimum color contrast ratio thresholds (color-contrast)
Fix any of the following:
  Element has insufficient color contrast of 2.74 (foreground color: #999999, background color: #ffffff, font size: 12.0pt, font weight: normal). Expected contrast ratio of 4.5:1

What’s actually happening

Light-gray-on-white body text, pale links, or low-contrast button labels that are legible to you but hard to read for low-vision users or anyone in bright sunlight. The automated finding comes from the axe-core 'color-contrast' rule (used by Lighthouse, axe DevTools, WAVE, and most scanners) and reports the exact foreground/background hex, the font size and weight, and the measured ratio versus the required one. This is the single most common accessibility failure: 83.9% of home pages in the February 2026 WebAIM Million had it.

Common causes

  • Light gray body text on white, such as #999 on #fff at 2.74:1, a default many themes ship with.
  • Brand-colored buttons or links where the text color was never checked against the fill (e.g. white text on a light blue or yellow).
  • Placeholder text and form hints in faint gray that fall well under 4.5:1.
  • Text laid over a photo or gradient where the underlying pixels vary and parts drop below threshold.
  • Theme or design-system color tokens chosen for looks without ever running a contrast check.

How to fix it

  1. Get the real ratio, don't eyeball itUse the WebAIM Contrast Checker or browser DevTools (Chrome shows a contrast ratio with a pass/fail checkmark in the color picker and the Inspect tooltip). You need 4.5:1 for normal text and 3:1 for large text, where large is 18pt/24px, or 14pt bold/19px and up.
  2. Darken the foreground or lighten nothing criticalNudge gray text darker until it passes, e.g. #767676 on white is exactly 4.54:1 and is the lightest gray that passes for body text. Fix it in your CSS variables/design tokens so every instance updates at once rather than patching one element.
  3. Fix text over images with a scrimFor text on photos or gradients, add a semi-transparent dark overlay, a text-shadow, or a solid backing behind the text so the effective contrast clears 4.5:1 at every point, not just on average.
  4. Don't forget placeholders, focus, and hover statesPlaceholder text, visited/hover link colors, and disabled-looking-but-active controls all get scanned. Walk each interactive state and re-check, since fixing the default color often leaves :hover or :focus still failing.
  5. Re-scan after changesRun axe DevTools or Lighthouse again on the updated pages to confirm the color-contrast violations are gone. Note scanners skip text over background images, so spot-check those by eye and with a manual sample.

Stop it recurring

Bake 4.5:1 minimum contrast into your design tokens and check every text/background and interactive-state pairing before it ships.

Related errors