WCAG contrast ratios in real product design — case studies and pitfalls

What a contrast ratio actually measures

A WCAG contrast ratio compares the relative luminance of two colours — text and its background — on a scale from 1:1 (identical) to 21:1 (pure black on pure white). The formula is (L1 + 0.05) / (L2 + 0.05), where L1 is the lighter colour's luminance and L2 the darker's. The key word is luminance, not hue: contrast is about how light or dark colours are, not how different they look.

That is why two vivid, obviously different colours can still fail. A medium red and a medium green can sit at almost the same luminance, giving a ratio near 1:1 — text in one on a background of the other is nearly unreadable, even though they are 'different colours'. Contrast and colourfulness are not the same thing.

The thresholds, precisely

WCAG 2 level AA requires 4.5:1 for normal text and 3:1 for large text. Large is defined as at least 24px (18pt), or 18.66px (14pt) when bold — a smaller pixel size qualifies as 'large' only if it is bold. Level AAA raises this to 7:1 normal and 4.5:1 large.

There is a separate rule people forget: success criterion 1.4.11 (non-text contrast) requires 3:1 for user-interface components and meaningful graphics — button borders, input outlines, icons, focus indicators — against their adjacent colours. Disabled controls are exempt from contrast minimums, but that exemption is widely abused to justify hard-to-see inactive states.

Where real designs fail

The most common failure is light-grey body text on white in the name of 'elegance'. A mid-grey like #999999 on white is only about 2.8:1 — it fails AA outright. Placeholder text is usually even lighter and almost never passes, yet teams routinely put real instructions in it.

Brand colours are another trap: plenty of mid-tone brand palettes fail AA for a button label on a white field, so the label has to darken or the button has to. Text over a hero image or a gradient is the subtlest case — the contrast ratio changes pixel by pixel, so a caption can pass over the dark part of a photo and fail over the bright part. Dark mode gets forgotten too: a low-contrast dark-grey-on-black is just as failing as its light-mode cousin.

The pitfalls a checker does not catch

A contrast checker compares two flat colours, but real text is not flat. A ratio that passes with a regular weight can read poorly in a hairline or light font, because the math ignores stroke width — thin glyphs put less ink on screen than the ratio implies. Small anti-aliased text effectively lowers contrast at the edges, too.

Two more traps: applying the large-text exemption to text that is bold but still small (it must meet the size threshold), and treating a passing ratio as full accessibility. Contrast (1.4.3) and not relying on colour alone (1.4.1) are separate requirements — a link that passes contrast but is distinguished from body text by colour only still fails. Always test text over images and gradients at the worst-case pixel, not the average.

WCAG 2 today, APCA tomorrow

The WCAG 2 ratio is useful but imperfect. Because it does not model font size, weight, or how human vision actually perceives light-on-dark versus dark-on-light, it can be too strict on some light-text combinations and too lenient on some dark ones. Designers feel this when a pairing 'looks fine' but fails, or 'looks thin' but passes.

The proposed replacement is APCA (the Accessible Perceptual Contrast Algorithm), explored for the future WCAG 3. APCA weights text size, weight, and contrast polarity, aiming to match perception more closely. It is not normative yet — you cannot claim conformance against it. The pragmatic stance: ship to WCAG 2 AA today, and watch APCA for where the standard is heading.

Takeaways

Memorise two numbers: 4.5:1 for body text, 3:1 for large text and UI components. Most decisions come back to those.

Do not trust grey-on-white 'elegance'#999 on white fails AA; check before you ship.

Test text over images and gradients at the worst pixel, not the average, because the ratio varies across the area.

A passing ratio with a hairline font still fails real readers — consider weight and size, not just the number.

Contrast and colour-independence are separate requirements — never use colour as the only signal. The colour-contrast checker on this site computes the WCAG 2 ratio and the AA/AAA result for any pair.