Skip to content

A best attempt at the screen reader pass, and a script for the rest - #20

Merged
RCheesley merged 2 commits into
mainfrom
screen-reader-pass
Sep 22, 2026
Merged

RCheesley merged 2 commits into
mainfrom
screen-reader-pass

Conversation

@RCheesley

Copy link
Copy Markdown
Owner

Partial work on #10. It does not close it, and the reason is the point.

What changed in code

A live region speaks when its contents change. Setting it to the string it already holds changes nothing, so the message is silent — and the messages most likely to repeat are the ones a learner most needs. Mistyping the same key twice in a row announced once.

announceInto toggles a trailing space so a repeat is always a genuine change. A trailing space rather than a zero-width space, because a zero-width space is read out as a character by some screen readers and a trailing one cannot be.

Only progress-view.ts is routed through it here. The drill surface — where this matters most — is contended by the sprint work in #8 and adopts it immediately after that merges.

What we cannot know from here

Whether a whitespace-only change counts as a change for every screen reader. It is the documented technique, it is what we have, and it needs confirming by ear. Same for three other things we found by reading rather than listening, all written up in the new doc.

The larger half: docs/screen-reader-testing.md

A twenty-minute script for somebody with VoiceOver, NVDA or Orca. It assumes no knowledge of the codebase, links the reference layout so a tester without a Glove80 can still do it, and covers loading, the board's aria-hidden claim, keyboard capture and escape, mistakes, the result, the ladder and the weak-key report.

It also says what is already asserted automatically, so nobody spends their time re-checking that keystrokes are not announced or that Escape releases the keyboard. Those are covered. What is not covered is whether any of it is usable.

Honestly

An agent can add live regions and assert their politeness. #6 already did that well: word announcements fire on word change rather than per keystroke, errors name the expected key and its finger, and the result is assertive while progress is polite.

What nobody has done is listen to it. Whether announcing the current word is the right granularity, whether the result is comprehensible heard rather than seen, whether the escape hint arrives in time to help someone who feels trapped — none of that is reachable from the code.

So #10 stays open and stays help wanted.

🤖 Generated with Claude Code

…g the rest

A live region speaks when its contents change, so setting it to the string it
already holds is silent. The messages most likely to repeat are the ones a
learner most needs: mistyping the same key twice in a row produces the same
sentence twice, and the second one was never spoken. announceInto toggles a
trailing space so a repeat is always a real change. A trailing space rather
than a zero-width space, because a zero-width space can be read out as a
character by some screen readers and a trailing one cannot.

Only the progress views are routed through it here. The drill surface is being
edited by the sprint work in parallel and will adopt it straight after, which
is where it matters most.

The larger half of this is docs/screen-reader-testing.md: a twenty minute
script for somebody with VoiceOver, NVDA or Orca. It says what to try, what is
already asserted automatically so nobody wastes time on it, and the four things
we suspect are wrong from reading the code rather than from listening. Whether
a whitespace-only change is treated as a change by every screen reader is one
of them, so the fix above is a best guess awaiting confirmation.

Nothing here replaces somebody listening to it. That is the point of the
document.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@RCheesley
RCheesley merged commit d5b50f8 into main Sep 22, 2026
3 checks passed
@RCheesley
RCheesley deleted the screen-reader-pass branch September 22, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant