Examples
Common HTML patterns and their predicted screen reader output. Each example shows the HTML input and what NVDA and VoiceOver would announce.
Button with aria-label
A button using aria-label overrides the visible text content for screen readers.
<button aria-label="Submit payment">Pay now</button>
"Submit payment, button"
"Submit payment, button"
Navigation landmark
A nav element with aria-label creates a named navigation landmark. Each screen reader announces landmarks differently.
<nav aria-label="Main"> <a href="/">Home</a> <a href="/about">About</a> </nav>
"Main, navigation landmark Home, link About, link"
"navigation, Main Home, link About, link"
Form with labels
Properly associated labels are announced before the input type.
<label for="email">Email address</label> <input type="email" id="email" />
"Email address, edit"
"Email address, edit text"
Heading hierarchy
Headings are announced with their level. Screen readers let users navigate by heading level, so proper hierarchy matters.
<h1>Welcome</h1> <h2>Getting Started</h2> <h3>Installation</h3>
"Welcome, heading level 1 Getting Started, heading level 2 Installation, heading level 3"
"heading level 1, Welcome heading level 2, Getting Started heading level 3, Installation"
Checkbox with states
Checkboxes announce their checked state. NVDA uses "not checked" / "checked" / "half checked" for mixed state.
<input type="checkbox" id="terms" /> <label for="terms">Accept terms</label> <!-- Checked --> <input type="checkbox" id="news" checked /> <label for="news">Subscribe</label> <!-- Mixed (indeterminate) --> <input type="checkbox" aria-checked="mixed" id="all" /> <label for="all">Select all</label>
"Accept terms, checkbox, not checked Subscribe, checkbox, checked Select all, checkbox, half checked"
"Accept terms, checkbox, unchecked Subscribe, checkbox, checked Select all, checkbox, mixed"
Image with alt text
Images with alt text are announced as graphics with their description. Images without alt text are flagged as missing accessible names in audit reports.
<!-- With alt text --> <img src="logo.png" alt="Speakable logo" /> <!-- Without alt text (accessibility issue) --> <img src="hero.png" />
"Speakable logo, graphic graphic"
"Speakable logo, image image"
Expandable button
Buttons with aria-expanded announce their expanded/collapsed state. Useful for accordions, dropdowns, and disclosure widgets.
<button aria-expanded="false">Show details</button> <!-- After clicking --> <button aria-expanded="true">Show details</button>
"Show details, button, collapsed Show details, button, expanded"
"Show details, button, collapsed Show details, button, expanded"
Table structure
Tables are announced with their dimensions. NVDA says "table", JAWS says "table with N rows and N columns", VoiceOver includes row/column counts.
<table>
<tr>
<th>Name</th>
<th>Role</th>
</tr>
<tr>
<td>Alice</td>
<td>Engineer</td>
</tr>
</table>"table
row
Name, column header
Role, column header
row
Alice
Engineer""table, 2 rows, 2 columns
row
Name, column header
Role, column header
row
Alice
Engineer"Semantic diff
Compare two HTML versions to detect accessibility changes. The diff shows added, removed, and changed nodes with property-level detail.
# Before (old.html) <button>Save</button> # After (new.html) <button aria-label="Save document">Save</button> # CLI command speakable new.html --diff old.html
# Diff output shows: Changed: root.children[0] name: "Save" → "Save document"
Selector filtering
Use CSS selectors to narrow analysis to specific elements. Useful for component-level testing.
<!-- page.html contains many elements --> <nav aria-label="Main">...</nav> <main> <button>Submit</button> <button>Cancel</button> </main> # Analyze only buttons speakable page.html --selector "button"
"Submit, button Cancel, button"