Checklists · 31 checks
The Developer's Accessibility Checklist
What to check before you open the pull request, in the order that finds the most.
The Developer's Accessibility Checklist
- Checks
- 31
- Time
- 20 minutes for a component, an hour for a full page
- Last reviewed
- August 28, 2026
Front-end developers reviewing their own work, and anyone doing a code review on a component or page.
Most accessibility defects are cheap while the branch is still open and expensive once they have shipped into forty templates, which is the whole argument for running this list before the pull request rather than after the audit. It is ordered so the checks that catch the most run first.
None of it needs a screen reader to start with. The keyboard alone finds a surprising share in about two minutes. Your browser's accessibility inspector finds most of the rest, with nothing to install.
Five groups. Semantics first, because nearly everything below traces back to it, then keyboard and focus, forms, anything the page does after load, and last the visual checks you can run in the window you already have open.
Semantics come first
Almost every problem in the sections below traces back to one thing, which is an element chosen for how it looked rather than for what it does. Fixing it here removes work from every group below. A real button arrives with its role, its keyboard handling and its focus behavior already attached.
Use the native element before reaching for a div.
Search the diff for `onClick` on a div or a span. Each one should have been a button or a link.
WCAG 4.1.2
Every control has an accessible name.
Open the accessibility panel in devtools and look at the Name field. If it is blank, a screen reader announces the role and nothing else.
WCAG 4.1.2
Headings are real headings, not styled text.
Read the heading outline on its own, and check three separate things while you are there. Anything presented as a heading has to be marked up as one, which is 1.3.1. Whether the heading actually describes its section is 2.4.6. Gaps in level are advice rather than a failure, so fix those for the reader and do not log them as a breach.
WCAG 1.3.1
Landmarks wrap the page regions.
Confirm there is one `main`, that navigation sits inside `nav`, and that nothing important is stranded outside a landmark. Landmarks are the other way people move around a page. They are also one of the documented routes past a repeated block.
WCAG 1.3.1
Lists are lists and tables are tables.
Data in a grid needs real `th` cells. W3C accepts `th` alone on a small table with one header row and distinct columns, and `scope` becomes the answer as soon as the headers are ambiguous. A stack of items needs `ul` or `ol`, not a run of divs.
WCAG 1.3.1
The page declares its language.
Check `lang` on the html element, which is 3.1.1. A passage written in another language needs its own `lang` too, and that one answers to 3.1.2 at AA.
WCAG 3.1.1
Keyboard and focus
Put the mouse away and use the feature. This takes two minutes and finds more real defects than any automated tool.
Every interactive element is reachable by Tab.
Tab through the whole component. Anything you can click but cannot reach is a failure.
WCAG 2.1.1
Tab into every widget, then keep going. If you cannot get out without the mouse, it is a trap. 2.1.2 has a second limb worth knowing, which is that a widget needing Escape or some other key conforms as long as it advises the user of that key.
WCAG 2.1.2
The focus indicator is always visible.
Watch the ring as you tab. Search the CSS for `outline: none` and confirm each one has a replacement.
WCAG 2.4.7
Focus order follows the visual order.
Tab through and check the order matches what you see. Absolute positioning and flex `order` are the usual causes of a mismatch.
WCAG 2.4.3
Sticky headers do not hide the focused element entirely.
Tab down a long page and watch for focus disappearing under a fixed bar. At AA the test is whether any of it still shows, and `scroll-padding` on the scrolling container fixes it. Covering it partly is a AAA failure, 2.4.12, and not an AA one.
WCAG 2.4.11
Focus moves sensibly when content changes.
Open a dialog and confirm focus enters it. Close it and confirm focus returns to what opened it.
No positive tabindex anywhere.
Search for `tabindex="1"` or higher. A positive value rearranges the tab order of the whole page and is almost always a mistake.
Forms and error handling
Forms are where accessibility failures turn into lost money, because a form that cannot be completed is a customer who leaves. Six checks. The last two pass a visual review and fail a real one.
Every input has a label, and the label is wired to it.
A missing label is what 3.3.2 catches. Click the label text, and if focus moves to the field the association works, which is the part 1.3.1 asks for.
WCAG 3.3.2
Placeholder text is not the only label.
Type one character into each field and watch what disappears. If the prompt vanishes, it was a placeholder rather than a label. Anybody interrupted comes back to a filled box with no idea what it wanted.
WCAG 3.3.2
Errors say what is wrong and how to fix it.
Submit the form wrong and read what comes back. A red border with no words is a failure. Color is not text, and it carries nothing to a blind reader. So is 'invalid input', which is a verdict rather than a suggestion, and this rule asks for the suggestion wherever your code knows one.
WCAG 3.3.3
Rendering the message on screen satisfies the error rule and does not satisfy this one. The words have to reach somebody who cannot see them, which means either moving focus to the error or putting it in a live region that was already in the page before the message arrived.
WCAG 4.1.3
Fields about the user carry an autocomplete attribute.
Name, email, address and phone fields each need the right token so browsers can fill them in. §7 scopes the input purposes to the user's own information, so a recipient's or an emergency contact's details are outside 1.3.5.
WCAG 1.3.5
Nothing submits or navigates on change.
Change a select with the arrow keys rather than the mouse and watch what happens. If the page navigates before you have confirmed anything, that is a change of context on input, and a keyboard user cycling through the options triggers it on every one of them.
WCAG 3.2.2
Anything the page does after load
A screen reader user cannot see something happen, so anything your page changes after it has loaded has to be announced rather than merely rendered. Single-page apps fail this group hardest. Every route change is a page load nobody was told about.
Status messages are announced.
A live region has to exist in the DOM before the message arrives. Adding both at once usually announces nothing.
WCAG 4.1.3
Expandable controls report their state.
Confirm `aria-expanded` sits on the trigger and flips when the panel opens, because putting it on the panel is the common mistake and it announces nothing. The state belongs to the control somebody has focus on, not to the thing that control reveals.
WCAG 4.1.2
Route changes move focus and update the title.
Navigate inside your single-page app and check two things afterwards. The document title changed, and focus did not stay sitting on the link that was clicked. Neither happens by itself when a framework swaps the view. Both need writing. Without them a screen reader user has no idea the page moved.
WCAG 2.4.2
Auto-playing or moving content can be paused.
Movement that starts on its own, runs past five seconds and sits beside other content needs a control. Content that auto-updates needs one from the first second, because the five-second allowance never reached it.
WCAG 2.2.2
The interface honours reduced motion.
Turn the reduced motion setting on in your operating system, reload, and watch the page again. Large parallax and slide transitions should be cut back or gone. For somebody with a vestibular disorder that movement causes real nausea rather than mild irritation.
Visual and responsive checks
Seven checks, all in the browser window you already have open. Between them they cover the failures reported most often on real sites. None takes longer than a minute.
Text meets the contrast threshold.
Check your body text, your placeholder text and your hover states, since devtools reports the ratio on any element you inspect. Two exceptions are worth knowing before you file anything. A disabled control is excepted by the rule itself, so a grayed-out button measuring short is not a finding, and neither is text that forms part of a logo.
WCAG 1.4.3
Borders, icons and focus rings meet 3 to 1.
Non-text contrast is a separate rule from the one for text and it is missed far more often, because measuring your body copy never makes you look at your input borders. Measure each against whatever sits next to it. Inactive controls are excepted, and so is anything the browser draws that you have not restyled.
WCAG 1.4.11
Nothing relies on color alone.
Screenshot the page and drop it to grayscale, then look for anything that has just become ambiguous. Required fields, validation states, chart series and links inside paragraphs are the four that usually go. Each needs a second signal, and the color can then stay exactly as it is.
WCAG 1.4.1
The page reflows at 320 pixels wide.
Set the viewport to 320 CSS pixels and look for sideways scrolling and for content clipped at the edge of its container. That width is what the rule is measured at. It is also a real phone, so anything failing here is already failing a large share of your traffic.
WCAG 1.4.10
Text zoom to 200 percent does not break the layout.
Text-only zoom is the sharper test, because page zoom scales the layout along with the words and hides the problem. It is the sharper test rather than the required one, though. Full-page zoom is a sufficient way to meet this rule, so a page that only enlarges that way has not failed. Look for overlap. Look for text cut off inside a container with a height set in pixels.
WCAG 1.4.4
Tap targets are at least 24 by 24.
Measure your smallest control, which is nearly always an icon button in a toolbar or a dialog close button. A smaller target still passes on spacing, if a 24 pixel circle centered on it overlaps neither another target nor the circle around another small target, which is why a tight row of footer icons fails even where each icon is fine alone.
WCAG 2.5.8
Images have the right alt text.
Decorative images take an alt attribute with nothing in it, and meaningful ones describe what they convey at that point on the page. Watch for the third case, which is an image whose information is already written next to it as real text. That one is redundant, takes an empty alt as well, and otherwise gets announced twice.
WCAG 1.1.1
One honest limit
Passing every line here does not mean the page passes WCAG, and it is worth saying so before anybody quotes a clean run in a review. This list covers what one developer can check alone at a desk. An audit adds screen reader testing, cognitive load, and the judgment calls no checklist can hold, which is most of what is left.
Keep going
Other checklists
Ticked every box and want it verified?
The full audit tests all 55 WCAG 2.2 A and AA rules with a pass or fail on each, adds an expert review, and puts a real blind screen-reader user on your key journeys. $499, report in 5 business days.