Skip to content
← All guidesGUIDE · UPDATED 2026-09-24

Colour contrast and WCAG: making text readable

How the contrast ratio works, the AA and AAA thresholds, real colour examples, and where contrast problems hide.

Low-contrast text is the most common accessibility failure on the web. Automated audits of large numbers of home pages keep finding it on the large majority of them. It affects far more people than you might expect: anyone with low vision, the roughly one in twelve men with a colour vision deficiency, older readers, and everyone reading a phone in sunlight. The good news is that contrast is one of the few accessibility properties you can measure exactly.

How the contrast ratio works

The Web Content Accessibility Guidelines (WCAG) define contrast as a ratio between the relative luminance of two colours: the lighter colour’s luminance plus 0.05, divided by the darker’s plus 0.05. The result runs from 1:1 (identical colours) to 21:1 (black on white). Relative luminance weights the red, green, and blue channels by how bright they appear to the eye. Green contributes most and blue least, which is why pure blue text on black is hard to read even though the colours look very different.

The thresholds

LevelNormal textLarge text
AA (the usual legal and policy target)4.5:13:1
AAA (enhanced)7:14.5:1

“Large” means at least 24 CSS pixels, or 18.66 pixels in bold. WCAG 2.1 and 2.2 also require 3:1 for meaningful non-text elements such as input borders, focus indicators, and icons that convey information. Level AA is what the European Accessibility Act, the EN 301 549 standard, and most accessibility policies point to.

Real examples

Measured with the contrast checker:

  • White on #2563eb (a strong blue): 5.17:1, passes AA for all text.
  • White on #3b82f6 (a lighter blue, a common default button colour): 3.68:1, which fails AA for normal-size button labels.
  • White on #16a34a (a typical “success” green): 3.30:1, which fails for normal text. Green buttons with white labels often need a darker shade.
  • Grey #6b7280 on white: 4.83:1, which passes AA and is a safe secondary-text grey.
  • Grey #9ca3af on white: 2.54:1, which fails. Many placeholder and “muted” text colours are this light.
  • Dark #1f2937 on amber #fbbf24: 8.79:1, which passes AAA. Dark text on bright colours often works better than white.

Where contrast problems hide

  • Placeholder text in form fields, which is often light grey and is the only label some forms have.
  • Disabled and secondary states. Disabled controls are exempt, but “secondary” buttons and helper text are not.
  • Text on images and gradients. Check the lightest and darkest points behind the text, or add a solid or translucent overlay.
  • Brand colours used for links and buttons. A brand colour that works for a logo may be too light for small text.
  • Dark mode. Every pair needs to be checked again, because a palette that passes in light mode can fail in dark mode.
  • Transparent colours. Semi-transparent text changes contrast depending on what is behind it. The checker composites the foreground over the background before measuring, as the screen would.

Fixing a failing pair

Adjust lightness rather than hue. In HSL terms, lowering the lightness of the text or raising the lightness of the background changes contrast the most while keeping the colour recognisable. Use the colour converter to move between HEX and HSL, nudge the lightness, and check again. Build a palette with each colour in several lightness steps. The palette generator is a starting point. Then decide once which steps are allowed for text on which backgrounds.

Contrast is not the whole story

Passing contrast ratios does not guarantee readable text. Very thin font weights, small sizes, long line lengths, and tight line spacing all reduce legibility, and never rely on colour alone to convey meaning. A red error message also needs an icon or text, because colour-blind users may not see the difference. WCAG 3 is expected to introduce a more perceptual contrast model. Until then, the WCAG 2 ratio is the measure that standards and audits use.

For text sizes that adapt to the screen without breaking zoom, see the guide on fluid typography with clamp() and type scales.