メインコンテンツへスキップ
Skip to docs content

Screen Reader Testing Checklist

A structured checklist for verifying screen reader accessibility with Speakable. Work through each category to catch common issues before they reach users. This complements, but does not replace, manual testing with real assistive technology.

Navigation

All landmarks have accessible names

Each nav, aside, and section should have a unique aria-label so screen reader users can distinguish them in the landmarks list.

CLI
speakable page.html -f audit | grep "landmark"

Heading hierarchy is sequential (no skipping levels)

Headings should follow a logical order (h1 → h2 → h3). Skipping from h1 to h3 confuses users who navigate by heading level.

CLI
speakable page.html -f audit

Skip navigation link is present and works

A visually hidden "Skip to content" link should be the first focusable element, letting keyboard users bypass repeated navigation.

CLI
speakable page.html -f text -s voiceover --selector "a[href='#main']"

Tab order matches visual order

Interactive elements should receive focus in the same order they appear visually. Avoid positive tabindex values.

CLI
speakable page.html -f json | node -e "const d=require('fs').readFileSync('/dev/stdin','utf8');const j=JSON.parse(d);console.log(j.filter(n=>n.focusable).map(n=>n.name))"

Forms

All inputs have associated labels

Every form control needs a programmatically associated label via for/id, wrapping, or aria-labelledby. Placeholders are not labels.

CLI
speakable form.html -f audit

Required fields are announced

Inputs with the required attribute or aria-required="true" should be announced as required by screen readers.

CLI
speakable form.html -f text -s nvda --selector "input[required]"

Error messages are linked to inputs

When validation fails, error messages should be associated via aria-describedby so they're announced when the input receives focus.

CLI
speakable form.html -f text -s jaws --selector "[aria-invalid]"

Fieldsets group related controls

Radio buttons and checkbox groups should be wrapped in a fieldset with a legend to provide group context.

CLI
speakable form.html -f text --selector "fieldset"

Dynamic Content

Status messages use aria-live regions

Content that updates dynamically (success messages, counters) should be in an aria-live="polite" region so screen readers announce changes.

Manual verification required: check source code directly.

Loading states communicate progress

Spinners and loading indicators should use role="progressbar" or aria-busy="true" to inform assistive technology that content is loading.

Manual verification required: check source code directly.

Toast notifications use role="alert"

Transient notifications should use role="alert" or aria-live="assertive" to interrupt the user and announce immediately.

CLI
speakable toast.html -f text -s all

Media

Images have alt text (or are decorative)

Informative images need descriptive alt text. Decorative images should use alt="" to be hidden from screen readers.

CLI
speakable page.html -f audit | grep "image"

Videos have captions/transcripts

Video content must have synchronized captions for deaf users and transcripts for deafblind users.

Manual verification required: check source code directly.

Icons used as buttons have accessible names

Icon buttons without visible text must have aria-label or visually hidden text to communicate their purpose.

CLI
speakable page.html -f text --selector "button"

Tables

Data tables have headers

Use <th> elements with proper scope attributes so screen readers can associate data cells with their column or row headers.

CLI
speakable table.html -f text -s nvda --selector "table"

Caption or aria-label identifies table purpose

Every data table should have a <caption> or aria-label that describes what data the table presents.

CLI
speakable table.html -f audit

Layout tables don't use table semantics

Tables used purely for layout should have role="presentation" to prevent screen readers from announcing table structure.

Manual verification required: check source code directly.

Custom Widgets

Custom controls have correct ARIA roles

Non-native widgets (tabs, accordions, menus) must have appropriate ARIA roles so screen readers announce their type correctly.

CLI
speakable widget.html -f text -s all

States are communicated (expanded, checked, etc.)

Dynamic states like aria-expanded, aria-checked, and aria-selected must update when the user interacts with the widget.

CLI
speakable widget.html -f json | grep "state"

Keyboard interaction follows ARIA patterns

Custom widgets should follow the ARIA Authoring Practices keyboard patterns (arrow keys for tabs, Enter/Space for buttons, etc.).

Manual verification required: check source code directly.

Suggested workflow

Start with speakable page.html -f audit to get an overview of issues, then use targeted selectors to verify specific elements. Integrate into your CI/CD pipeline to catch regressions automatically.

Related Pages