Introduction
Screen readers are how blind and low-vision users experience the web. They read content aloud, announce UI structure, and provide keyboard shortcuts for navigation. Testing with screen readers is the only way to truly verify your accessibility — automated tools catch about 30% of issues.
The three major screen readers are VoiceOver (macOS/iOS, built-in), NVDA (Windows, free), and JAWS (Windows, commercial). Each interprets HTML and ARIA slightly differently, so testing with at least two is recommended.
This guide covers how to use each screen reader, what to listen for, and a testing checklist for common UI patterns.
Key Concepts
VoiceOver on macOS
# Enable: Cmd + F5 (or System Settings → Accessibility → VoiceOver)
# Basic navigation:
# VO = Control + Option (the VoiceOver modifier)
VO + Right Arrow # Move to next element
VO + Left Arrow # Move to previous element
VO + Space # Activate (click) current element
VO + U # Open rotor (headings, links, landmarks)
VO + Shift + Down # Enter a group/table
VO + Shift + Up # Exit a group/table
Tab # Next focusable element
Shift + Tab # Previous focusable element
VO + H # Read current heading level
NVDA on Windows
# Download from nvaccess.org (free)
# NVDA key = Insert (default) or Caps Lock
NVDA + Down Arrow # Read from current position
Tab # Next focusable element
H # Next heading
D # Next landmark
K # Next link
F # Next form field
NVDA + F7 # Elements list (headings, links, landmarks)
NVDA + Space # Toggle forms/browse mode
What to Listen For
- Element role — 'button', 'link', 'heading level 2', 'navigation landmark'
- Element name/label — 'Submit button', 'Search, edit text'
- State — 'expanded', 'collapsed', 'checked', 'disabled', 'selected'
- Context — 'list, 5 items', 'table, 3 columns, 10 rows'
Practical Examples
1. Testing a Navigation Menu
// What VoiceOver should announce:
// "Navigation, main" (landmark)
// "Home, link" (first item)
// "Products, collapsed, popup button" (dropdown)
// After expanding: "Products, expanded, popup button"
// "Category A, link" (submenu item)
// Common issues:
// - Menu not announced as navigation landmark
// - Dropdown state (expanded/collapsed) not announced
// - Focus doesn't move into submenu on expand
// - No way to close menu with Escape key
2. Testing a Dialog/Modal
// Expected behavior:
// 1. Focus moves to dialog on open
// 2. Screen reader announces dialog title
// 3. Tab cycles within dialog (focus trap)
// 4. Escape closes dialog
// 5. Focus returns to trigger element
// Test:
<dialog aria-labelledby="dialog-title" aria-describedby="dialog-desc">
<h2 id="dialog-title">Confirm Deletion</h2>
<p id="dialog-desc">This action cannot be undone.</p>
<button onClick={onCancel}>Cancel</button>
<button onClick={onConfirm}>Delete</button>
</dialog>
3. Testing Checklist
## Screen Reader Testing Checklist
### Page Structure
- [ ] Page title is descriptive
- [ ] Headings form a logical hierarchy (h1 → h2 → h3)
- [ ] Landmarks are present (nav, main, footer)
- [ ] Skip link works and jumps to main content
### Interactive Elements
- [ ] All buttons have accessible names
- [ ] Links describe their destination (not "click here")
- [ ] Form fields have associated labels
- [ ] Error messages are announced
- [ ] Custom widgets announce role and state
### Dynamic Content
- [ ] Toast/notification is announced
- [ ] Loading states are communicated
- [ ] Content changes are announced via live regions
- [ ] Modal focus trapping works correctly
Best Practices
- ✅ Test with at least two screen readers (VoiceOver + NVDA)
- ✅ Navigate by headings to verify heading hierarchy
- ✅ Test all interactive flows — forms, dialogs, dropdowns, tabs
- ✅ Listen for element role, name, and state announcements
- ✅ Test with screen reader in both browse mode and forms mode
- ❌ Don't test only with automated tools — they miss interaction issues
- ❌ Don't add aria-label to everything — too much labeling is noisy
Common Pitfalls
- Testing only with VoiceOver — NVDA and JAWS behave differently with ARIA
- Not testing dynamic content — SPAs frequently break screen reader announcements
- Forgetting to test with different verbosity settings — users customize their experience
- Using VoiceOver cursor instead of Tab — real users primarily use Tab for interactive elements
Related Guides
- WCAG Practical Guide — The standards you're testing against
- ARIA Attributes Guide — Understanding what ARIA screen readers interpret
- Keyboard Accessibility Guide — Keyboard is the foundation of screen reader navigation
- Accessibility Testing Tools — Complement manual testing with automation