Enough screen reader to catch yourself
You are not going to become a screen reader user, and pretending otherwise is the reason developers skip this entirely — the target is a dozen NVDA and VoiceOver keystrokes that catch your own mistakes before a real user has to.
You are not going to become a screen reader user. Somebody who uses NVDA every day operates it at a speed and with a mental model you will not acquire on a Tuesday evening, and any tutorial implying otherwise is selling something. That gap is the actual reason developers skip this step: the honest version of the task looks enormous, so it never gets started, and the component ships having been checked by nobody.
The task is smaller than that. You are not evaluating whether the interface is good. You are checking whether it says what you think it says. Does the approve control announce as a button. Does it have a name. Does the confidence chip get announced at all. Every one of those is a yes-or-no answer available in a handful of keystrokes, and every one of them is a mistake you made and can fix.
The size of the ask, stated by the people teaching it
WebAIM’s own framing of its NVDA article is that it is “designed to help new or novice NVDA users learn how to test web content”, and it is candid about the ramp: “Plan on spending some time (perhaps a few hours) becoming comfortable using NVDA.” A few hours, once, for a capability you keep. WebAIM is a nonprofit that also sells accessibility training, which is worth naming whenever you quote them, and it cuts against their commercial interest to tell you the ramp is short.
The two to learn are NVDA on Windows and VoiceOver on macOS, for a plain reason: both are free, and between them they cover the two machines you already have. That reason is deliberately not a market-share argument. WebAIM’s Screen Reader User Survey #10 collected 1,539 valid responses in December 2023 and January 2024 and reports JAWS at 40.5%, NVDA at 37.7% and VoiceOver at 9.7% as primary screen readers. Those numbers get quoted as market share constantly, and WebAIM says plainly that they are not: “The sample was not controlled and may not represent all screen reader users.” A self-selected survey is useful context and cannot settle which screen readers your product must support. Cite it for what it is or do not cite it.
NVDA: the commands that do the work
Install it, and during setup choose CapsLock as the NVDA modifier key, which is what WebAIM recommends and what makes every command below reachable one-handed. The commands, from the article:
| Key | What it does |
|---|---|
NVDA + ↓ | Start reading at the current position |
Ctrl | Stop reading. The one you will use most. |
NVDA + ↑ | Reread the current line |
Tab | Move to the next link or form control |
H | Next heading. Add Shift to go backwards, as with all of these. |
D | Next landmark |
B / F / T | Next button, form control, table |
NVDA + F7 | Open the Elements List: every link, heading, form field and button on the page, as a list |
NVDA + Space | Toggle between browse mode and focus mode |
Learn that last one first. In browse mode, single-letter keys are navigation commands, which is how H jumps between headings. In focus mode, keystrokes pass through to the browser so you can type into a field. WebAIM notes that NVDA switches automatically in most cases and that NVDA + Space toggles the modes manually. Almost every confusing first session with a screen reader is the mode being the opposite of what the tester assumed. If your custom combobox swallows a letter key and nothing happens, check the mode before you file a bug.
VoiceOver: the same job, a different modifier
VoiceOver is already on the Mac. Start it with Command + F5, adding fn on laptops where the function row needs it. The modifier is Control + Option, written VO everywhere in the documentation.
VO+Astarts reading;Controlalone stops it.VO+→andVO+←step through items one at a time. This is the one you will live in.VO+Command+Hjumps to the next heading; swapHforLfor links,Jfor form controls,Tfor tables.VO+Spaceactivates the link or control you are on.VO+Uopens the rotor, which is VoiceOver’s equivalent of the Elements List.Shift+VO+Ireads webpage statistics, which is a fast sanity check on whether the page has any headings at all.
One caveat matters more than any command, because it changes what your test result means. WebAIM: “VoiceOver currently functions best with the Safari web browser.” A screen reader is not a property of a component. It is half of a pair with a browser, and the pair is what behaves. “It works with VoiceOver” is not a claim. “VoiceOver with Safari on macOS, tested on this date” is.
The four checks worth doing every time
This is the loop. It takes about five minutes per component once the keystrokes are in your fingers, which is the whole argument for spending the few hours.
- Tab through and listen to the names. Every control should announce a name, a role, and its state where it has one. A button that announces as “button” with no name is 4.1.2 Name, Role, Value, Level A, heard rather than inferred. An icon button whose name is the icon’s file name is the same failure wearing a disguise.
- Press H repeatedly. You are checking that the heading structure exists and matches the visual hierarchy. A panel that looks like a section and is built from a bold
divis silent here, which is 1.3.1 Info and Relationships, Level A. - Open the Elements List or the rotor. This shows you the page the way a screen reader user actually navigates it, as a list of links, headings and buttons stripped of layout. If your component is incomprehensible in that view, it is incomprehensible in use.
- Operate the widget without looking. Turn the monitor off or close your eyes. Open the field picker, choose an option, confirm the choice was announced. This is the step that finds the missing announcement, because your eyes stop covering for it.
Check four is also where the APG’s own warning gets satisfied. That guide says testing assistive technology interoperability is essential before shipping code from it, and the four patterns you built in the previous lesson have not been listened to yet.
Where people get burned
What this does not make you is a substitute for a screen reader user. You are checking your own work for defects you can name, in a tool you barely operate. A component that survives your test is a component whose obvious mistakes are gone, which is a real and useful claim. Anything stronger than that belongs to people who use these tools every day, and if your conformance note implies otherwise it has stopped being honest.
Check your recall
Answer from memory — no scrolling back.
Retrieval check
Name the NVDA keystrokes for: start reading, stop reading, next heading, the elements list, and the browse/focus toggle. Then name the VoiceOver modifier and the rotor.
Check your answer
- Start reading:
NVDA+↓ - Stop reading:
Ctrl - Next heading:
H, in browse mode, with Shift for the reverse - Elements List:
NVDA+F7 - Browse / focus toggle:
NVDA+Space - VoiceOver modifier:
Control+Option, writtenVO - Rotor:
VO+U
If you produced the commands but not the browser pairing, that is the half that matters in a conformance note. VoiceOver functions best with Safari, per WebAIM, so a support claim names the browser or it names nothing.
Hands on
Retire “none verified” from the conformance note
Done when: The accessibility-supported field in CONFORMANCE.md names at least one screen reader and browser pair with the date it was tested, and explicitly names the combinations that were not tested. At least one new finding in the table came from something you heard rather than saw.
- Install NVDA, or start VoiceOver with
Command+F5and open Safari. Give yourself the couple of hours WebAIM says it takes before you judge how it went. - Run the four checks above on the review gate. Write down what you heard in the words you heard, not in the words you expected. The difference between the two is the entire finding.
- Take the widgets you tabled in the four-patterns lesson and operate each one with your eyes shut. Confirm that state changes are announced, not just present in the DOM. A correct
aria-expandedthat is never announced is still worth knowing about. - Fill the accessibility-supported field with a pair and a date. Then, in the same cell, name what you did not test. An entry that lists JAWS as untested is stronger than one that quietly omits it.
- Add every new failure to the findings table with a criterion number, a level and a cost, and mark the provenance
human. Add the combinations you did not test to the “checked by nobody” list. That list should get longer today, not shorter. - Bring the accessibility-supported field into the chat. I will push on any claim broader than the pair you actually tested, and on any finding you would not repeat with the monitor off.
What this does not cover
This module ends with four patterns built against the guide, a focus contract you can test in ninety seconds, and a conformance note whose supported set is finally something you stood behind. All of it applies to interfaces that hold still.
Point any of it at a token stream and it comes apart. Every keystroke here assumes content that is there when you go looking for it, and a streaming response is content that changes while it is being read. The announcing-the-stream lesson opens the next module on exactly that, and it opens on an empty shelf: the W3C’s own editor’s draft on the accessibility of machine learning and generative AI, checked again while this course was written, has nothing to say about announcing incrementally generated text. The pattern has to be built out of 4.1.3 Status Messages, aria-busy, and the Understanding document’s own warning about being too chatty, and the course says where that reasoning came from rather than dressing it up as a citation.
Read this next — primary source
Using NVDA to Evaluate Web AccessibilityWebAIM (Utah State University) — free. A nonprofit that also sells accessibility training and consulting, so it has an interest in the subject even though this particular article sells nothing.
Written for exactly the person this lesson is for: a sighted developer testing their own work, not someone learning to use a screen reader daily. It gives the install and configuration steps, the reading and navigation command tables this lesson draws from, and a clear explanation of browse mode versus focus mode, which is the single concept that separates useful testing from confusing testing. It is also honest about the ramp, telling you to plan on a few hours before you are comfortable, which is the kind of estimate a vendor tutorial tends to leave out.
Stuck, curious, or think this lesson is wrong? Ask your teaching agent. The lessons are the scaffold; the conversation is where the learning gets unstuck.