Why Developers Should Test With Screen Readers
Automated tools can't tell you what a screen reader user actually experiences. A button might have a label, but is it a helpful label? A modal might be accessible, but does it trap focus properly? Screen reader testing answers these questions.
Getting Started
VoiceOver (macOS, built-in)
- Press Cmd + F5 to toggle VoiceOver on/off
- Use VO keys (Control + Option) plus arrow keys to navigate
- VO + Space to activate buttons and links
- VO + U to open the rotor (a quick nav menu for headings, links, etc.)
NVDA (Windows, free)
- Download from nvaccess.org
- Insert key is the NVDA modifier
- Use Tab to jump between interactive elements
- Use heading keys (H) to navigate by heading level
- Insert + F7 opens the elements list
JAWS (Windows, commercial)
- Use Insert as the JAWS key
- Tab / Shift+Tab for interactive elements
- H / Shift+H for next/previous heading
- Insert + F5 for form fields list
What to Test
- Page structure: Are headings in the correct hierarchy? Is the landmark structure logical?
- Links and buttons: Do they have descriptive labels? Does "click here" make sense out of context?
- Forms: Are labels associated with their fields? Are error messages announced?
- Dynamic content: When content changes, is the user informed? Are live regions used appropriately?
- Images: Is alt text meaningful? Are decorative images hidden from assistive technology?
Common Issues and Fixes
| Issue | Fix |
|---|---|
| Button says "Submit" but context is unclear | Add an aria-label: "Submit contact form" |
| Screen reader reads "image" with no description | Add meaningful alt text |
| Modal doesn't trap focus | Add focus management with JavaScript |
| Dynamic content appears without announcement | Use aria-live="polite" on the container |
| Heading levels skip from h1 to h4 | Fix heading hierarchy to be sequential |
Build the Habit
Test with a screen reader for 5 minutes during each pull request. You'll catch more issues than any automated tool, and you'll develop an intuition for accessible code that improves everything you build.