A checklist for code-generating assistants
Eighteen checks an assistant can run on its own HTML and CSS before returning it, each tied to a stable rule id and a test corpus page.
Code assistants produce a large share of new interface code. Most of it is reviewed by a person who is checking whether it works, not whether it works for everyone. The assistant is the last step with full attention on the code, so it is the right place for the accessibility check.
Below are the checks, in the order they are cheapest to run. Each has a rule id from the ruleset and a planted example in the test corpus, so an assistant can be tested on them.
Structure (run first, they are string checks)
html langis set andtitleis page-specific. AW-STRUCT-002.- The viewport meta does not contain
user-scalable=noor amaximum-scalebelow 2. AW-STRUCT-003. This one is a blocker: it stops people from zooming at all. - One
h1, and heading levels never skip downward. AW-STRUCT-001.
Names (the most common blockers)
- Every
imghas analtattribute. AW-ALT-001. - No alt starts with "image of" and no alt is a file name. AW-ALT-002, AW-ALT-003.
- An image that is the only content of a link or button names the destination. AW-ALT-004.
- Every form control has a label.
label for, a wrappinglabel, oraria-label. A placeholder does not count. AW-NAME-001. - Every button and link has a non-empty accessible name. Icon-only buttons need
aria-label. AW-NAME-002. - Link text names the destination. Not "click here", not "read more". AW-NAME-003.
Keyboard
- Anything clickable is a
buttonor ana href. Adivwith anonclickis invisible to the keyboard. AW-KEY-001. - No
tabindexabove zero. AW-KEY-002. - Nothing is reachable only by hover. Every
:hoverthat reveals content has a:focus-withintwin or a visible toggle. AW-KEY-003.
Focus (the ones static tools miss)
- No focus selector sets
outline: nonewithout a replacement ring in the same rule. AW-FOCUS-001. Grep foroutline: noneandoutline: 0; for each hit on a:focusor:focus-visibleselector, confirmbox-shadowor a border change in the same block. - The ring reaches 3:1 on every background it can land on. AW-FOCUS-002. Compute it. A two-tone ring passes everywhere; see why agents miss focus states.
- Custom focus styles use
:focus-visible, not bare:focus. AW-FOCUS-003.
Color and motion
- Every text-on-background pair you introduced reaches 4.5:1 (3:1 for large text). AW-COLOR-001. Not just body text. The muted caption, the badge, the placeholder.
- Error, success, and selected states use more than color. An icon, a word, an underline. AW-COLOR-002.
- Animation and long transitions are reduced under
prefers-reduced-motion: reduce. AW-MOTION-001.
How to report
Return findings as a list, each with the rule id, a selector, the severity from the rule, and one sentence that says what is wrong and what to change. Do not report a rule you did not actually test. If you could not test something, for example a focus ring on a background you cannot compute, say that instead of guessing.
How to know you are getting better
Run your checks on the fourteen corpus pages and compare against the expected findings by rule id and selector. Page 14 is clean on purpose; anything reported there is a false positive. Precision and recall over the corpus are a number you can watch move.