Skip to content

explainer

Contrast and readability in docs themes (WCAG AA in practice)

A brand colour that looks right on a marketing page is often unreadable as a link in body text, and worse again in dark mode. What AA actually requires, which parts of a docs theme break first, and how to stop choosing badly.

published · 6 min read

the short version

AA is 4.5:1 for body text and 3:1 for large text and interface parts. The two things that break it in almost every docs theme are the brand colour used as a link on white, and the same brand colour carried unchanged into dark mode. Check both schemes, or derive the palette so you cannot pick a failing one.

The numbers, and what they apply to

WCAG contrast is one ratio between two colours, and at AA there are only three thresholds worth memorising.

WhatRatio at AANotes
Body text4.5:1Anything under 18.5px, or under 14px bold
Large text3:118.5px and up, or 14px and up if bold
Interface parts and graphics3:1Borders, icons, focus rings, form outlines
Disabled controlsExemptBut nobody should have to read them
LogosExemptYour wordmark is not held to this

AAA raises body text to 7:1, which is a fine goal and a hard constraint to design a brand inside. AA is the line most teams are actually held to, and it is the line worth enforcing automatically.

Contrast is measured against the colour actually behind the text, not against the page background. Text on a tinted callout, a code block or a table header is a separate check, and those are exactly the places a theme quietly fails.

What breaks first in a docs theme

In practice the failures cluster. Five places account for nearly all of them, and four involve a brand colour being asked to do a job it was not chosen for.

1. The brand colour as a link

This is the big one. A brand blue picked to look good on a hero image lands somewhere around 3:1 on white — fine as a large heading, a failure as an inline link in a paragraph. Because links are the most-clicked text on a docs page, it is also the worst place to fail.

2. The same colour in dark mode

A colour with 4.6:1 on white will often sit near 2:1 on a near-black background. Dark mode is not the light theme inverted; every foreground needs re-checking against its new background, and a brand colour usually has to be lightened to survive the trip.

3. Muted secondary text

The grey used for timestamps, captions and helper text. Designers push it down until it stops competing with the body, and it very often lands between 3:1 and 4.5:1 — legible on a good monitor in a dark room, and not on a laptop outdoors.

4. Code blocks

Syntax themes are designed against their own background and then dropped into yours. Comments are the usual casualty: deliberately dimmed, and frequently the least readable text on the page despite often being the part that explains what the code does.

5. Focus rings and borders

Held to 3:1, and routinely softened into invisibility because a designer thought the outline was ugly. A focus ring nobody can see makes the site unusable by keyboard, which is a bigger failure than any colour choice.

Deriving a palette instead of picking one

The usual fix is a checklist: pick your colours, run them through a checker, adjust, repeat for dark mode. It works, and it fails the moment someone changes the brand colour without repeating it.

The alternative is to take one colour and compute the rest. You give the system a brand colour and it works out what that colour has to become to do each job — the link colour in light, the link colour in dark, hover, active, a tint for backgrounds, and the text colour that has to sit on top of the brand colour itself — checking each against the background it will actually appear on.

  • The brand colour stays recognisable, because everything derives from its hue.
  • Lightness moves where it has to, which is what contrast actually depends on.
  • Both schemes are solved at once, so dark mode cannot be the thing nobody checked.
  • A bad choice cannot ship, because the failing combination is never produced.

This is what Docszero does. You pick one brand colour; hover, active, tint and on-colour text are derived on the server, and links and text are checked at 4.5:1 in both the light and the dark scheme. Nothing you can choose makes a page hard to read.

How to check your own theme in ten minutes

If you maintain your own theme, this is the short version of an audit that catches nearly everything.

  • Open a real page with a paragraph, an inline link, a list, a table, a callout and a code block. Not a component gallery — the combinations only happen on a real page.
  • Run the browser’s own accessibility audit in both light and dark. Chrome and Firefox both report contrast failures with the two colours and the ratio.
  • Check the link colour inside a callout and inside a table cell, not only on the page background.
  • Tab through the page and watch for the focus ring on every interactive element, including skip links and anything inside a code block.
  • Check the code comment colour specifically, in both schemes.
  • Zoom the browser to 200%. AA expects the page to still work, and fixed-height containers usually do not.

Two things worth saying about automated checks. They catch contrast well, because it is arithmetic. They cannot tell you whether your link colour is distinguishable from your body colour for a reader with a colour vision deficiency — for that, make sure links carry an underline or another non-colour signal, which is a WCAG requirement in its own right and one no ratio will surface.

Questions

What contrast ratio does WCAG AA require?

4.5:1 for body text, and 3:1 for large text — 18.5px and up, or 14px and up when bold — and for interface parts such as borders, icons and focus rings. AAA raises body text to 7:1. Logos and disabled controls are exempt, though disabled text nobody can read is still a usability problem.

Why does my brand colour fail as a link colour?

Brand colours are usually chosen against large type, images or a coloured panel, where 3:1 is the bar. An inline link in a paragraph is body text, so it needs 4.5:1 against the page background. A colour that looks confident in a hero often lands just under that, which is why links are the most common AA failure in a docs theme.

Does dark mode need separate contrast checks?

Yes, always. Contrast is between a foreground and the background it actually sits on, so every colour needs re-measuring against the dark background. A colour that passes comfortably on white commonly lands near 2:1 on near-black, and usually has to be lightened to work in both schemes.

Is an automated contrast checker enough?

For contrast, largely yes — it is arithmetic on two colours. It will not tell you whether links are distinguishable from body text without colour, whether focus order makes sense, or whether a diagram carries its meaning in the prose around it. Underline your links and keep a visible focus ring regardless of what a checker says.

How does Docszero handle this?

You choose one brand colour and the rest of the palette is derived on the server — hover, active, tint and the text colour that sits on the brand colour. Links and text are checked at 4.5:1 in both the light and the dark scheme of each theme, so a combination that fails is never produced. The four themes ship with light and dark schemes on Pro and Agency; Free sites use the Zero theme.

Try the free plan instead of reading about it

One site, your own docszero.com subdomain, full-text search and the export button, free forever and without a card. Pro is $19.99 a month when you want your own domain, your own look and the badge gone.

  • Drag in a folder of Markdown, a zip, a Word document or a PDF
  • Search, navigation and a 404 page are built for you
  • Export the built site or the source on every plan, free included