The game
Fifty two cards, split evenly. Flip the top cards, higher rank takes both, ties mean war. Everything that happens is written to a hidden live region, and mirrored into the transcript so sighted visitors can watch an invisible feature work.
A screen reader gets nothing from the canvas itself.
The game is still fully playable. Flip with the button or the F key, and follow the announcements in the transcript.
Round 0 路 You 26 cards 路 Computer 26 cards
Keyboard: press F to flip. Space and Enter also work when a button is focused.
What the screen reader hears
A mirror for sighted visitors only. This list is deliberately not a live region, so screen reader users hear each announcement once, from the hidden status zone, not twice.
- Nothing yet. Flip a card.
Why this page exists
The problem
A canvas is a rectangle of pixels. Games love it because anything can be drawn there. Screen readers cannot use it, because assistive technology reads the document tree, and a canvas has almost no tree to read. Every card in the game above, every score, every win, is just paint. A blind player can find the buttons on this page and press them, and still learn nothing about what happened, because the results are only ever drawn.
The technique
The fix is one hidden element and one habit. The element is a status zone: a visually hidden region marked
role="status" with aria-live="polite", so a screen reader speaks whatever is written into it
without interrupting. The habit is to write a short sentence into it for every event that is worth drawing, in the game's
own words, with the score attached:
<div id="sr-announcer" class="sr-only" role="status"
aria-live="polite" aria-atomic="true"></div>
function announce(message) {
const el = document.getElementById('sr-announcer');
el.textContent = '';
setTimeout(() => { el.textContent = message; }, 40);
}
The repeat gotcha
Live regions only speak when their text changes. Flip the same winning card twice in a row and the second announcement
is identical to the first, so the screen reader stays silent and the player misses a whole round. That is why
announce() clears the region first and writes on a short delay. The clear and rewrite is what makes a repeated
event get spoken again. It is a small detail, and it is the difference between a player following the game and a player
guessing.
Focus tells you where you are. This tells you what happened.
Keyboard support and focus management answer the question "how do I act, and where am I?" They say nothing about outcomes. Announcements close that loop: act by keyboard, hear the result. Neither half is optional. Together they make a canvas game a game again for someone who cannot see it.
Exactly what Classic Scoundrel does
This is not a simplified cousin of the real thing. Classic Scoundrel, a full roguelike card game drawn on canvas, uses the same hidden status zone and the same clear-then-write announce call for every card play, potion, room change, and game over. War is just the smallest game that proves the point. If an event is worth drawing, it is worth saying. On canvas, the developer is the accessibility tree. There is nobody else.
Play Classic Scoundrel, the game this technique comes from.