Testing it: keyboard, screen reader and axe
Five lessons of rules are worth less than one testing habit. This lesson is the habit: three passes, in increasing cost, that between them catch nearly everything you will realistically ship.
You have met parts of it already. This is the whole thing in order, so you can run it.
Pass 1: the keyboard, one minute
No software. Put your mouse away and press Tab from the top of the page.
Ask five questions:
- Can I reach everything interactive? Every link, button, field, control.
- Can I see where I am? A visible ring on every single stop.
- Is the order sensible? Roughly the order things appear. No jumping.
- Can I operate everything? Enter on links, Enter and Space on buttons, arrows in radio groups and selects, Escape to close.
- Can I get out? Tab all the way round, back to the address bar. No trap.
Then two specific checks:
- Tab down a long page and confirm focus never lands under a sticky header.
- Open anything that opens — a dialog, a menu — and check where focus goes on open and on close.
This pass finds more real problems than anything else in the lesson, which is why it is first and why it is worth doing on every change.
Pass 2: automated, one minute
axe DevTools is the best of these. Install the browser extension, open devtools, find the axe panel, and scan. It reports issues grouped by severity with the exact element and a link explaining each one.
Lighthouse is built into Chrome — the Lighthouse panel, tick Accessibility, analyse. Fewer checks than axe but no installation.
The Issues panel flags some accessibility problems continuously as you browse, with no scan needed. Worth glancing at.
What they reliably catch: missing alt, unlabelled form fields, insufficient contrast
between declared colours, missing lang, duplicate ids, invalid ARIA, aria-labelledby
pointing at nothing, nested interactive elements, missing document title.
What they cannot catch — and this is the reason pass 1 comes first:
- Whether
alt="chart"describes the chart. - Whether the heading order makes sense.
- Whether the focus order is logical.
- Whether
aria-expandedis accurate. - Whether an error message tells you what to do.
- Whether "read more" means anything.
A perfect axe score on a page you cannot use with a keyboard is entirely possible. Roughly a third of issues are machine-detectable.
Scan every state, not just the initial page. Open the menu and scan. Open the dialog and scan. Submit the form with errors and scan. Most tools only see the DOM as it is now, and the states are where the problems live.
Pass 3: a screen reader, ten minutes
The pass people skip, and the one that changes how you write markup. You do not need to become fluent — you need to hear your own page once.
Which one, and how to start it
| Platform | Screen reader | Start |
|---|---|---|
| macOS | VoiceOver | Cmd + F5 |
| Windows | NVDA (free) | download, then Ctrl + Alt + N |
| Windows | Narrator | Ctrl + Win + Enter |
| iOS | VoiceOver | Settings → Accessibility, or triple-click the side button |
| Android | TalkBack | Settings → Accessibility |
Use Safari with VoiceOver and Firefox or Chrome with NVDA — those are the combinations real users use and the ones best supported.
The ten commands you need
VoiceOver — VO means Ctrl + Option:
Cmd + F5 start / stop
VO + A read from here
Ctrl shut up (press it the moment you need to)
VO + → / ← next / previous item
VO + U the rotor — headings, links, landmarks, form controls
VO + Cmd + H next heading
VO + Space activate
Tab next focusable, as normal
VO + Shift + ↓ enter a group; VO + Shift + ↑ leave it
NVDA — Insert is the modifier:
Ctrl + Alt + N start
Insert + ↓ read from here
Ctrl stop talking
H next heading
D next landmark
K next link
F next form field
Insert + F7 the elements list
Insert + Q quit
Learn the stop key first. A screen reader reading a whole page at you while you panic is the reason most people give up in the first minute.
What to actually do
Do not read the page top to bottom. Use it the way a real user would:
- Open the elements list or rotor and read the headings. Do they summarise the page?
This is the module's
semantic-structuretest, heard rather than inspected. - List the landmarks. Is there a
main? Are two navs distinguishable? - List the links. Do they make sense out of context? Count the "read more"s.
- Tab through the form. Is every field named? Is the hint read? Is the error read when you focus the field?
- Land on a table cell. Do you hear the row and column headers, or just the value?
- Open a dialog. Is its purpose announced? Does Escape work?
- Look at an image-heavy section with your eyes closed. Does the
alttext carry the page, or is it a list of filenames?
Write down what you could not understand. That list is your work.
What you will find, reliably
Everybody finds these the first time:
- A button announced as just "button", because its label is an icon with no name.
- An image announced as
img_20260927.jpg. - Three links called "read more".
- A form field with no name — "edit text, blank".
- A menu button that never says whether it is open.
- A table read as a stream of numbers with no headers.
- Something focusable and completely silent.
Pass 4: the other emulations, two minutes
In the devtools Rendering panel, switch each of these on and look:
prefers-color-scheme: darkprefers-reduced-motion: reduceprefers-contrast: moreforced-colors: active- Vision deficiencies — and achromatopsia is the fastest single check, because if the page works with no colour it works for every deficiency.
Then, without devtools:
- Zoom to 200%, and to 400% if you can. WCAG asks for reflow at 320px equivalent, which is what 400% zoom on a 1280px window produces.
- Switch off the stylesheet entirely. Does it still read as a document?
- Switch off images. Does the
alttext carry the meaning?
A checklist you can actually run
Print this, or keep it in the repo.
Keyboard
- Everything interactive reachable by Tab.
- Visible focus ring on every stop, 3:1 contrast.
- Focus order matches visual order.
- Enter and Space both work on buttons.
- Escape closes dialogs and menus.
- No focus trap — Tab round and out.
- Focus never hidden under a sticky header.
- Focus returns to the trigger when something closes.
Structure
9. One <h1>, no skipped levels, outline reads as a contents page.
10. <main> present, landmarks labelled where duplicated.
11. Lists are lists; tables have <caption> and scope.
12. lang on <html>, and on any foreign-language span.
13. A unique, specific <title>.
14. Reading order is DOM order.
Content
15. Every image has an alt that replaces it — alt="" if decorative.
16. Link text makes sense out of context.
17. Nothing conveyed by colour alone.
18. Contrast: 4.5:1 text, 3:1 large text and boundaries.
19. Form fields have real <label>s; errors use aria-describedby and say what to do.
20. Captions on anything with speech.
Behaviour 21. Reduced motion honoured. 22. Nothing flashes more than three times a second. 23. No timeout the user cannot extend. 24. Zoom to 200% and 400% without loss.
Tooling 25. axe or Lighthouse clean — in every state, including open menus and error states. 26. Heard once with a screen reader.
Build the habit, not the audit
A single audit before launch finds a pile of expensive problems. Small checks continuously find them when they are cheap.
Per change: tab through what you just built. Ten seconds.
Per component: read its computed Name and Role in the Accessibility pane.
Per page: run axe, and run the keyboard pass properly.
Per release: the full checklist, plus the screen reader.
And the two questions worth asking during design rather than after, because at that point they are free:
"How does this work with a keyboard?" Asked before you build a custom dropdown, it
usually produces a <select> or a <details> instead — which is module 1's argument
arriving from the other direction.
"What does this say if you cannot see it?" Asked of a chart, a status dot or an icon button, it produces the text you would otherwise have to retrofit.
Check your work
Which pass to do first, and why. The keyboard — it needs no software and finds the most.
The five keyboard questions. Reach, see, order, operate, escape.
How much automation catches. About a third, and only the mechanical third.
What it cannot judge. Whether alt is right, whether the outline makes sense, whether
aria-expanded is accurate, whether an error is actionable.
What most people forget to scan. The other states — open menus, dialogs, error states.
Which screen reader on which platform. VoiceOver with Safari; NVDA with Firefox or Chrome.
The first command to learn. How to make it stop — Ctrl.
How to use a screen reader like a user. Lists and jumps, not reading top to bottom.
The fastest colour check. Achromatopsia.
What 400% zoom is equivalent to. Reflow at about 320px.
The two design-time questions. How does this work with a keyboard, and what does it say if you cannot see it.
Practice
- Tab through your capstone. Write down every failure against the five questions.
- Fix them, then tab through again.
- Install axe DevTools and scan. Compare its findings with your keyboard list.
- Scan again with a dialog open and with a form in its error state. Note the extra findings.
- Run Lighthouse and compare its count with axe's.
- Start your platform's screen reader and learn the stop key before anything else.
- List your page's headings with the rotor or the elements list. Judge the outline.
- List the links. Count the ones that are meaningless out of context.
- Tab through your form with the screen reader on. Note every field with no name.
- Land on a table cell and see whether you hear the headers.
- Close your eyes and try to understand an image-heavy section from
alttext alone. - Emulate dark mode, reduced motion, forced colours and achromatopsia in turn.
- Zoom to 200% then 400%. List what breaks.
- Switch off the stylesheet, then images.
- Read the computed Name and Role for every interactive element on one page.
- Run the full 26-point checklist on your capstone and record the result.
- Pick any well-known Indian website and run passes 1 and 2 on it. You will find problems on almost all of them, which is worth seeing.
Official documentation
- Deque — axe DevTools — The extension, and what each rule checks.
- W3C WAI — Easy checks: a first review — A short manual review anybody can do, from the standards body.
- W3C WAI — Evaluating web accessibility overview — How a full evaluation is structured, and where tools fit.
- WebAIM — Using VoiceOver to evaluate web accessibility — The commands and a testing procedure.
- WebAIM — Using NVDA to evaluate web accessibility — The same for Windows.
- Chrome DevTools — Accessibility features reference — The Accessibility pane, the tree, and the contrast tools.
- W3C — How to meet WCAG (Quick Reference) — Filter to AA and use it as the authoritative version of the checklist above.
You can now build a page that works for somebody using a keyboard, a screen reader, a magnifier, high contrast mode, or no colour vision — and, more usefully, you can check that it does in about fifteen minutes.
Next module: modern CSS — custom properties, the selectors that replaced a lot of JavaScript, and shipping the thing.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship