Bhinish Dhiman

Why 14px body text can never pass APCA

APCA scores contrast against font size and weight, and at 14px regular there is no colour pair that clears its threshold — not even black on white. The fix is typographic, not chromatic. Use 16px, or keep 14px and set it in a heavier weight.

The first time a contrast tool tells you that black text on a white background fails, you assume the tool is broken. It usually is not. If the text is 14px at regular weight, APCA considers it unusable regardless of what colours you choose.

This surprises people enough to be worth explaining properly.

Contrast is not only about colour

WCAG 2 treats contrast as a property of two colours. Give it a foreground and a background and it returns a ratio, with no knowledge of how the text will be set.

APCA treats contrast as a property of two colours and the shape of the glyphs rendered in them. This is closer to how vision works. What reaches your eye is not an abstract colour pair, it is a quantity of ink arranged in strokes. Thin strokes at small sizes deliver very little of it, and antialiasing lightens them further at the edges.

So APCA’s thresholds move with typography. Its reference table gives, for each contrast level, the minimum font size usable at each weight:

Lc Weight 300 Weight 400 Weight 500 Weight 700
90 21px 16px 15.5px 14px
75 24px 18px 16px 14px
60 42px 24px 21px 16px
45 72px 42px 32px 24px

Read along the weight-400 column. At Lc 90 — which is close to the maximum available, since pure black on pure white is Lc 106 — the smallest usable size is 16px.

There is no row where 14px at weight 400 appears. Increasing contrast cannot help, because 16px is already the floor at the highest contrast the display can produce.

What you can do instead

Set it at 16px. The simplest fix, and the one most body text should have anyway. 16px has been the sensible default for body copy for a decade.

Keep 14px and add weight. Look at the weight-700 column: 14px is usable at Lc 90 and Lc 75. A 14px bold label with strong contrast is fine by APCA. This is often the right answer for UI labels where vertical space is genuinely constrained.

Reconsider whether it needs to be text. A 14px light-grey timestamp that nobody can read is not conveying information. Either it matters, in which case make it legible, or it does not, in which case remove it.

The uncomfortable corollary

Once you accept the table, a lot of common interface conventions stop being defensible.

The 11px or 12px uppercase label, in a muted grey, is everywhere in modern design systems. Under APCA, 12px at weight 400 has no passing contrast at all, and even at weight 700 it needs an extremely high Lc. We ran this check against our own interface while building this site and had to move our labels from 11px to 13px and add weight. The tool found the problem in its own chrome.

Placeholder text is the other common offender — small, light, and frequently the only label a field has.

WCAG 2 is not wrong, only incomplete

It means WCAG 2 is incomplete on this specific axis, which its authors knew. Modelling size and weight in 2008 would have required data and computation that were not practical at the time. A ratio of two luminances was a reasonable approximation and it has done an enormous amount of good.

But you should know what it cannot see. A 12px caption and a 32px headline in the same colours receive the same WCAG score, and only one of them is readable.

What to do in practice

Keep recording the WCAG ratio, because that is what conformance is measured against. Use APCA as the check on whether the thing can actually be read at the size you are shipping it.

And when APCA fails a colour pair at a small size, resist the instinct to darken the colour. Check the table first. Very often the answer is not a different colour — it is 2px more, or one weight heavier.

Our contrast checker reports both figures at your chosen size and weight, and when a size is unusable at any contrast it says so directly rather than reporting a failure you cannot fix with colour.