Screen readers convert visual interfaces into audio. The user hears the page content, navigates by headings and landmarks, and interacts with forms and controls through keyboard commands. A product that works well visually can be unusable with a screen reader if the underlying structure is wrong: missing headings, unlabeled buttons, images without alt text, dynamic content that changes silently, and reading order that does not match the visual layout.
This template provides a structured optimization guide for making your product work well with screen readers. It covers seven areas: document structure, headings, landmarks, link and button text, forms, dynamic content, and reading order. For each area, you get the requirements, common mistakes, and a verification checklist.
Use this template after the automated checks in the accessibility audit template have been completed. Automated tools catch missing alt text and contrast failures, but they cannot tell you whether the reading order makes sense or whether your headings create a coherent outline. The ARIA checklist template covers the ARIA attributes that make custom widgets accessible to screen readers. For testing the results of your optimization work, the assistive tech testing template provides structured protocols for VoiceOver, NVDA, and TalkBack.
How to Use This Template
Pick a page or user flow to optimize. Work through one page at a time rather than auditing the entire product at once.
For each of the seven areas below, review the page against the checklist criteria.
Open the page in a screen reader as you audit. VoiceOver on macOS (Cmd+F5) or NVDA on Windows (free download) are the most accessible starting points for teams new to screen reader testing.
Document findings with specific page locations and the expected versus actual screen reader behavior.
Fix issues in priority order: document structure and headings first (they affect every user on every page), then forms and dynamic content (they affect specific interactions), then fine-tuning reading order and announcements.
Retest with a screen reader after fixes. Screen reader behavior depends on the browser, so test in at least two browser and screen reader combinations (Safari+VoiceOver and Chrome+NVDA cover the majority of users).
The Template
Optimization Overview
Field
Details
Product / Feature
[Name]
Optimization Lead
[Name]
Date
[Date]
Pages/Flows Reviewed
[List pages or flows]
Screen Readers Tested
[VoiceOver + Safari / NVDA + Chrome / etc.]
Area 1: Document Structure
Why it matters: Screen reader users rely on document structure to understand the page's content hierarchy. Without proper structure, the page is a flat stream of text with no way to skip to relevant sections.
Criterion
Status
Notes
Every page has exactly one that describes the page's primary content
☐ Pass / ☐ Fail
The element accurately describes the page (announced on page load)
☐ Pass / ☐ Fail
The element has a lang attribute matching the page language
☐ Pass / ☐ Fail
Lists use
, , or
elements (not styled
elements)
☐ Pass / ☐ Fail
Data tables use
with
for headers and
for the table title
☐ Pass / ☐ Fail
Layout tables are not used (use CSS grid or flexbox instead)
☐ Pass / ☐ Fail
, , , , and elements define page regions
☐ Pass / ☐ Fail
Sections of different languages are marked with lang attributes
☐ Pass / ☐ Fail
Area 2: Heading Hierarchy
Why it matters: Screen reader users navigate by headings more than any other method. The WebAIM survey found that 67.5% of screen reader users use headings as their primary navigation method. A correct heading hierarchy lets users jump to the section they want in seconds.
Rules:
One per page (the page title)
No skipped levels (no followed by )
Headings describe the content that follows (not decorative text)
Every major section starts with a heading
Check
Status
Notes
Only one on the page
☐ Pass / ☐ Fail
No skipped heading levels (h1 > h2 > h3 > ...)
☐ Pass / ☐ Fail
Every section of content has a heading
☐ Pass / ☐ Fail
Headings are descriptive (not "Section 1" or styled paragraphs)
☐ Pass / ☐ Fail
Visual headings use actual heading elements (not bold or
)
☐ Pass / ☐ Fail
Hidden headings (for screen reader navigation) use .sr-only class, not display:none
Document the current heading outline above. Flag any deviations from a clean hierarchy.
Area 3: Landmarks
Why it matters: Landmarks are the screen reader equivalent of a page layout. Users jump between landmarks to quickly reach the navigation, main content, search, or footer without Tabbing through every element.
Required landmarks:
Landmark
HTML Element
Required?
Content
Banner
Yes (one per page)
Site header with logo and navigation
Navigation
Yes (one or more)
Primary and secondary navigation menus
Main
Yes (one per page)
The page's primary content
Complementary
If applicable
Sidebar content, related links
Search
or role="search"
If applicable
Site search form
Content Info
Yes (one per page)
Site footer with links and copyright
Check
Status
Notes
element wraps the primary content
☐ Pass / ☐ Fail
element wraps the site header
☐ Pass / ☐ Fail
elements wrap navigation menus
☐ Pass / ☐ Fail
Multiple elements each have a unique aria-label
☐ Pass / ☐ Fail
element wraps the site footer
☐ Pass / ☐ Fail
Search form is wrapped in or role="search"
☐ Pass / ☐ Fail
Landmarks do not overlap or nest incorrectly
☐ Pass / ☐ Fail
Area 4: Links and Buttons
Why it matters: Screen reader users can pull up a list of all links or buttons on a page. Each link's text must make sense out of context. "Click here," "Read more," and "Learn more" are useless in a link list because they do not describe the destination.
Check
Status
Notes
Every link's text describes the destination or action
☐ Pass / ☐ Fail
No links with generic text ("click here", "read more", "learn more") without aria-label context
☐ Pass / ☐ Fail
Links that open in new tabs/windows indicate this (aria-label including "opens in new tab" or visual indicator)
☐ Pass / ☐ Fail
Image links have alt text describing the link destination (not the image)
☐ Pass / ☐ Fail
Buttons use or role="button", not without href or
☐ Pass / ☐ Fail
Button text describes the action ("Save project" not just "Save" when multiple save actions exist)
☐ Pass / ☐ Fail
Adjacent links to the same destination are combined (not "Product Image" link + "Product Name" link)
☐ Pass / ☐ Fail
Skip-to-content link is the first focusable element on every page
☐ Pass / ☐ Fail
Common fixes:
Problem
Fix
"Read more" link
Change to "Read more about [topic]" or use aria-label="Read more about [topic]"
Icon-only button
Add aria-label="Search" (or whatever the action is)
"Click here"
Rewrite: "Download the Q3 report" instead of "Click here to download"
Image inside a link
Set alt text to the link destination: "Product roadmap guide"
Area 5: Forms
Why it matters: Forms are where screen reader users perform actions: logging in, searching, filling out profiles, making purchases. A form without proper labels is like a paper form where someone erased all the questions but left the blank lines.
Check
Status
Notes
Every form field has a visible element associated via for/id
☐ Pass / ☐ Fail
Required fields are indicated in the label (not just by asterisk color)
☐ Pass / ☐ Fail
Form groups use and (radio groups, checkbox groups, address blocks)
☐ Pass / ☐ Fail
Error messages are associated with their fields via aria-describedby
☐ Pass / ☐ Fail
Error messages are announced when they appear (via aria-live or role="alert")
☐ Pass / ☐ Fail
Form validation errors identify the field and describe the error
☐ Pass / ☐ Fail
Autocomplete attributes are set for common fields (name, email, address, phone)
☐ Pass / ☐ Fail
Submit button text describes the action ("Create account", not just "Submit")
☐ Pass / ☐ Fail
Placeholder text is not the only label (screen readers may not announce it reliably)
☐ Pass / ☐ Fail
Form instructions appear before the form, not after
☐ Pass / ☐ Fail
Area 6: Dynamic Content
Why it matters: Screen readers read a snapshot of the page at load time. When content changes dynamically (search results update, a toast appears, a counter increments, new chat messages arrive), the screen reader does not know about it unless ARIA live regions announce the change.
Check
Status
Notes
Success and error notifications use aria-live regions or role="alert"/role="status"
☐ Pass / ☐ Fail
Live regions exist in the DOM at page load (not dynamically created)
☐ Pass / ☐ Fail
Search results count is announced when results update ("12 results found")
☐ Pass / ☐ Fail
Loading states are announced ("Loading..." when starting, "Content loaded" when done)
☐ Pass / ☐ Fail
Chat messages or real-time updates use aria-live="polite" (not assertive)
☐ Pass / ☐ Fail
Page content that changes without a full reload updates the and focus position
☐ Pass / ☐ Fail
Modals, drawers, and popovers manage focus correctly (see focus management patterns)
☐ Pass / ☐ Fail
Content removed from the page does not orphan the user's focus position
☐ Pass / ☐ Fail
Area 7: Reading Order
Why it matters: Screen readers read the DOM in source order, not visual order. If CSS positions a sidebar visually on the right but the sidebar's HTML comes before the main content in the source, screen reader users hear the sidebar first. Similarly, CSS order in flexbox can create visual reordering that does not match the DOM order.
Check
Status
Notes
DOM order matches the visual reading order (top-to-bottom, left-to-right for LTR)
☐ Pass / ☐ Fail
CSS order, position: absolute, and flexbox/grid reordering do not create confusing sequences
☐ Pass / ☐ Fail
Visually hidden content (.sr-only) appears in a logical position in the DOM
☐ Pass / ☐ Fail
Content injected via JavaScript appears in the correct DOM position
☐ Pass / ☐ Fail
tabindex values do not override the natural tab order (no tabindex > 0)
☐ Pass / ☐ Fail
How to verify: Use the browser's accessibility tree (Chrome DevTools > Elements > Accessibility tab) to see the order screen readers will follow. Compare it to the visual layout.
Page Optimization Summary
Area
Criteria
Pass
Fail
Priority Fixes
Document Structure
8
Heading Hierarchy
6
Landmarks
7
Links and Buttons
8
Forms
10
Dynamic Content
8
Reading Order
5
Total
52
Screen Reader Compatibility Notes
Feature
VoiceOver (Safari)
NVDA (Chrome)
NVDA (Firefox)
JAWS (Chrome)
aria-live="polite"
Supported
Supported
Supported
Supported
role="switch"
Supported
Supported
Supported (recent)
Supported
landmark
Supported (Safari 17+)
Supported (Chrome 118+)
Supported
Partial
inert attribute
Supported
Supported
Supported
Partial
aria-description
Supported (Safari 16+)
Supported
Supported
Not supported (use aria-describedby)
CSS content in ::before/::after
Announced
Announced
Announced
Announced
Check the latest support tables at a11ysupport.io before relying on newer ARIA features.
Frequently Asked Questions
Which screen reader should we prioritize for testing?+
Prioritize VoiceOver with Safari on macOS and NVDA with Chrome on Windows. These two combinations cover the majority of screen reader users in the 2025 WebAIM survey. If you can only test with one, use NVDA with Chrome because it is free, runs on the most common OS (Windows), and Chrome is the most popular browser. The [accessibility compliance template](/templates/accessibility-compliance-template) includes a decision matrix for choosing your test matrix based on your user demographics.
How do we handle screen reader support for single-page applications?+
SPAs create unique challenges because page navigations do not trigger a full page load event. Screen readers do not automatically announce the new page. Three things need to happen on every client-side route change: update `document.title` to reflect the new page, move focus to the main content area or page heading, and optionally announce the page transition via an `aria-live` region. The [focus management template](/templates/focus-management-template) covers the focus restoration pattern in detail.
Should we add visually hidden text for screen readers?+
Use visually hidden text (`.sr-only` or `clip-path` technique) when the visual context provides information that the audio context lacks. Examples: a star rating that shows 4 filled stars needs `.sr-only` text saying "4 out of 5 stars." An icon button needs `.sr-only` text or `aria-label` describing the action. However, do not add hidden text as a band-aid for poor structure. If a heading or label is needed, make it visible rather than hiding it.
How do screen readers handle CSS-generated content?+
Content inserted via CSS `::before` and `::after` pseudo-elements with the `content` property is announced by all major screen readers. This means decorative CSS content (arrows, bullets, icons via `content: "\2022"`) will be read aloud. Use `content: "" / ""` with `aria-hidden="true"` on the parent or the pseudo-element to suppress the announcement, or use SVG icons with `aria-hidden="true"` instead of CSS content.
What is the difference between aria-label and aria-labelledby for screen readers?+
Both provide an accessible name. `aria-label` takes a string value directly. `aria-labelledby` takes one or more element IDs and reads their text content as the label. `aria-labelledby` is preferred when visible text exists because it stays in sync automatically. `aria-label` is preferred when no visible text exists. Note that `aria-label` on non-interactive elements (like `<div>` or `<span>`) is inconsistently supported. Use it on interactive elements (buttons, inputs, links, landmarks) where support is reliable. The [ARIA checklist template](/templates/aria-checklist-template) covers the full set of ARIA attributes and their correct usage.
Explore More Templates
Browse our full library of PM templates, or generate a custom version with AI.