Skip to content

axe

axe is a rules engine that inspects a rendered page and reports accessibility violations. It is the engine inside most accessibility tooling, so you are probably running it whatever the wrapper is called.

It belongs in two places, both of which already exist for other reasons:

  • Per story — a violation is attributed to a component, and it is caught before the component reaches a screen.
  • Per journey step — a violation in composition, which no component-level scan can see.

Wiring it into both is an afternoon’s work and it is the cheapest defect-per-hour available anywhere in this hub.

  • missing or empty accessible names
  • insufficient text contrast
  • form controls with no associated label
  • invalid ARIA: roles missing required children, states on elements that cannot carry them
  • duplicate, missing or misnested landmarks
  • some heading-order problems
  • images with no alternative text, and decorative images not marked as decorative

These are real defects, they regress constantly, and humans are bad at spotting them by eye.

axe checks mechanical properties of the DOM. It has no model of meaning, so it cannot see:

  • alternative text that exists and describes the wrong thing
  • a keyboard path that works and takes forty tabs
  • a focus order that is sequential and follows no visual logic
  • an error announced before the person reached the field
  • a live region that announces so often it is unusable
  • whether the reading order matches the visual order in a complex layout

The commonly cited figure is that automated scanning finds around a third of real barriers. Treat the scan as a floor, never as coverage — see accessibility tests for the manual pass that covers the rest.

Fail the build. A scan that reports into a dashboard is a metric. A scan that fails a build is a contract clause.

Choose the rule set deliberately, and record the choice — which conformance level, which optional rules. A default nobody chose is a default nobody defends when it gets in the way.

Disable a rule in one place, with a reason. Never repo-wide, never silently. A disabled rule with a comment and a ticket is a decision; a disabled rule without one is a hole.

Do not chase zero at the expense of the manual pass. A product can pass every axe rule and be unusable with a screen reader. Optimising the number that is easy to measure, at the cost of the thing that matters, is the standing risk of every automated check — and this is the one where the consequence lands on a person.