Skip to content

Accessibility

A page works from the keyboard and from a screen reader: landmarks, one h1, a skip link, a visible focus ring, text at 4.5:1, and a name on every control. An axe scan of the rendered pages is part of review.

The document shell is <header>, <main id="main">, and <footer>. Navigation has an accessible name, from aria-label or a heading. The skip link is the first focusable control, points at the main element’s id, and stays visually hidden until :focus.

The page has one h1. Later headings do not skip a level. A reusable heading component takes the level as an argument.

Focus uses :focus-visible. The ring is at least 2px, with a 2px offset, in a colour that clears 3:1 against the pixels behind it. A triple ring (colour, gap, colour) is valid when the gap colour is a token.

Text colours are tokens that pass 4.5:1 on the surfaces where they sit. A mid-scale brand step is not body text on white until the pair is measured. Placeholder text is text and uses the same bar.

Every input, select, and textarea has a <label> tied to its id, or an aria-label where a visible label is wrong. A control that opens a panel is a <button>. aria-controls is the id of the panel, not the id of the bar the button sits in. Attributes are quoted: aria-hidden="true".

A carousel or dialog that sets aria-label also sets a role (region or dialog). aria-label on a plain div is not a name.