Accessibility

The conformance target this design system holds itself to, the contrast and keyboard requirements that follow from it, and how the system reports its own open findings.

The standard

Every component in this system is measured against WCAG 2.2, Level AA. That is the target for the components themselves and for any page assembled from them.

A conformance target is a bar, not a badge. This system publishes its own validation results, and the report is expected to show open findings at any given time. A component with a live finding is a component that has been measured, not one that has been excused. The rule is that findings are visible, tracked and closed, never suppressed to make a report look clean.

Automated tooling catches roughly a third of WCAG failures. The rest needs a person with a keyboard and a screen reader.

Contrast

Text has to clear these ratios against its own background:

ContentMinimum ratio
Body text (under 18px, or under 14px bold)4.5:1
Large text (18px and above, or 14px bold and above)3:1
Icons, borders and other non-text UI3:1
Disabled controlsNo requirement, but avoid relying on them to convey state

Practical consequences:

  • A colour that passes at heading size can fail at body size. Check the pairing at the size it is actually used.
  • Accent colours chosen for brightness are the usual source of failures. Bright yellows and mid greens rarely clear 4.5:1 on white.
  • Never fix contrast by making the text bigger unless the design genuinely calls for larger text.
  • Colour is never the only carrier of meaning. Pair it with a label, an icon or a shape.

Keyboard access

Everything operable by mouse has to be operable by keyboard.

  • Tab and Shift+Tab reach every interactive element in a sensible order.
  • Enter activates links, Enter and Space activate buttons.
  • Escape dismisses anything layered over the page.
  • Arrow keys move within a composite widget such as tabs or a menu.
  • Focus is always visible. Never remove an outline without replacing it.

Two traps show up repeatedly:

  • Scrollable regions. A container that scrolls but holds no focusable child is unreachable by keyboard. Give it tabindex="0" and an accessible name so it can be scrolled with arrow keys.
  • Focus escaping a dialog. When a modal opens, focus moves into it and stays there until it closes, then returns to the trigger.

Semantics

  • Use the element that means what you want. <button> for actions, <a href> for navigation. A <div> with a click handler is neither.
  • One <h1> per page, and no skipped heading levels.
  • Landmarks on every page: <header>, <nav>, <main>, <footer>. Give a unique aria-label to a landmark that appears more than once.
  • A skip link is the first focusable element on the page.
  • ARIA is a last resort. Native semantics are correct by default and cannot fall out of sync.

Images and icons

HTML
1<!-- Meaningful image: describe what it conveys --> 2<img src="chart.png" alt="Revenue rising from 40 to 65 percent across four quarters"> 3 4<!-- Decorative image: empty alt removes it from the accessibility tree --> 5<img src="pattern.svg" alt=""> 6 7<!-- Icon beside text: the text is the label --> 8<svg aria-hidden="true" focusable="false"></svg> 9 10<!-- Icon-only control: label the control, not the icon --> 11<button type="button" aria-label="Close"> 12 <svg aria-hidden="true" focusable="false"></svg> 13</button>

Forms

  • Every input has a visible <label> tied to it by for and id.
  • Placeholder text is not a label. It disappears on focus and often fails contrast.
  • Error messages sit next to the field, describe the fix, and are linked with aria-describedby.
  • Required fields are marked in text, not only with a coloured asterisk.

Motion and timing

  • Respect prefers-reduced-motion for anything that moves, parallaxes or autoplays.
  • Content that animates in must still be present when animation is suppressed.
  • Nothing flashes more than three times per second.
  • Carousels and auto-advancing content need a pause control.

Review checklist

Run this before a component is considered done:

  • Tab through it. Everything reachable, focus always visible, order matches the visual layout.
  • Zoom to 200%. No content lost, no horizontal scroll.
  • Turn off colour. Every state still readable.
  • Run an automated scan and read the findings rather than the score.
  • Listen to it once with a screen reader. VoiceOver on macOS or NVDA on Windows.

Tools

ToolUse
axe DevToolsAutomated rule scan in the browser
WebAIM Contrast CheckerChecking a single colour pairing
NVDA / VoiceOverScreen reader testing
Keyboard onlyThe cheapest test, and the one that finds the most