Screen Readers
Date: 2026-08-17
Software that reads an interface aloud, navigating by its structure. Most of what makes a site work with one is using the right HTML element — and most of what breaks it is ARIA added to markup that didn’t need it.
A screen reader converts the interface into speech or braille, letting a user navigate by structure — headings, landmarks, links, form controls — rather than by looking.
It reads the accessibility tree, not the visual page — a parallel structure the browser derives from your markup — The Accessibility Tree.
How people actually navigate
The most important thing to understand, because it changes what matters:
NOT top-to-bottom, word by word
INSTEAD
jump between HEADINGS
→ "list of 14 headings"
jump between LANDMARKS
→ nav, main, footer
jump between LINKS
→ "list of all links"
jump between FORM CONTROLS
read the current element
Heading structure is navigation. A page with one <h1> and no other headings offers no way to skim — the user must read linearly or leave.
Link text out of context is a list. “Click here” repeated eleven times is eleven identical entries in the links list. Link text must make sense alone — Microcopy.
The readers in use
NVDA Windows, free, widely used
JAWS Windows, commercial,
common in enterprise
VoiceOver macOS and iOS, built in
TalkBack Android, built in
Narrator Windows, built in
Behaviour differs between them, and between browser pairings. Something working in VoiceOver/Safari may not in NVDA/Firefox — which is why testing on one is a start rather than a conclusion.
[CHECK: current screen reader usage-share surveys before citing specific proportions — these are published periodically and shift.]
What breaks it
DIVS AS BUTTONS
<div onclick> → no role, not
focusable, no keyboard
→ invisible as a control
MISSING LABELS
an input with only a placeholder
→ announced as "edit text, blank"
IMAGES WITHOUT ALT
→ the filename is read out
HEADING LEVELS SKIPPED OR VISUAL
<h4> used because it looked right
→ the structure lies
DYNAMIC UPDATES, SILENT
the basket count changes, nothing
is announced
→ Feedback and System Status
FOCUS NOT MANAGED
a modal opens, focus stays behind it
→ Focus Management
ARIA ADDED TO WORKING HTML
role="button" on a <button>
→ redundant at best
See: Feedback and System Status · Focus Management
The first rule of ARIA
No ARIA is better than bad ARIA.
<!-- correct: nothing needed -->
<button>Add to basket</button>
<!-- an accurate reimplementation -->
<div role="button" tabindex="0"
onclick="add()" onkeydown="…">
Add to basket
</div>
<!-- broken: role without behaviour -->
<div role="button" onclick="add()">
Add to basket
</div>The third is worse than a plain div, because it announces itself as a button and then doesn’t behave like one. The native element brings the role, focusability, keyboard handling and state for free — Semantic HTML.
Announcing dynamic changes
<div aria-live="polite">
Added to basket. 3 items.
</div>aria-live="polite" announced when
the user pauses
aria-live="assertive" interrupts
→ errors only
role="status" polite, built in
role="alert" assertive, built in
The region must exist in the DOM before the content changes. Inserting a live region and its message simultaneously frequently announces nothing — a common and confusing bug.
Testing without expertise
You don’t need fluency to find the big problems:
1 turn on VoiceOver (Cmd+F5) or NVDA
2 close your eyes, or turn off the
monitor
3 attempt to buy something
4 note every point you're stuck or
confused
An hour of this finds more than any automated scan, and the failures are unambiguous — you either completed the purchase or you didn’t — WCAG.
Screen reader users are experts at their tool. Your fumbling isn’t representative of their speed — but a barrier that stops you will stop them too.