Search topics
Task boards that say nothing when a card moves
A card moves to another column by its button or by a drag, but its new place shows only on screen, in the column and the counts, and nothing in a live region says where it went.
list.append(card); The problem
Screen reader users move a card and hear nothing about where it went, so they can't tell whether the move worked without leaving the card to read the column.
A team's task board has three columns, To do, Doing and Done, each with the number of its cards beside its heading. The board was built to work without dragging: every card has a button for each column it can go to, and the drag is still there for anyone who prefers it. Press Move to Done on "Write release notes" and the card jumps into Done, To do's count drops from 2 to 1, Done's rises from 0 to 1, and focus follows the card to its first button in the new column. A sighted user sees it land. A screen reader user hears "Move to To do, button, Write release notes": the name of the button focus landed on. Nothing says the card is now in Done, or that the move worked at all. The only clue is that the card's buttons now offer other columns, which they have to work out for themselves. To be sure, they leave the card, find the Done heading and read down its list, and then find their way back. A board is where work changes state, so this happens many times a day.
"Write release notes moved to Done" is a status message: it reports the result of something the person did, and it doesn't take focus. On screen, that result is shown twice, by the card in its new column and by the counts in the headings. Success Criterion 4.1.3 asks that such a message can be presented to assistive technology through a role or a property, so that it is announced without focus moving to it. Here the counts are in no live region, and nothing else says where the card went, which is failure F103. Moving focus to the card doesn't make up for it: focus lands on a button that keeps its own name, "Move to To do", and the card's title is read as its description, so a screen reader says what the button would do next, not what just happened. The browser has nothing else to report. Moving an element in the DOM is silent: the page has to put the result into words for assistive technology, usually by writing them into a region it is already watching.
The board works for people who can see it whole, because the card's new place is the confirmation. A board with many cards, or one that a narrow window turns into a single long column, makes that place hard to find for anyone who can't take it in at a glance.
1 of 10 groups affected
- No vision (affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (not affected)
- Seizures (not affected)
- Without vision Screen reader users press Move to Done and hear the button that focus lands on, not where the card went. To be sure, they leave the card, find the Done heading and read down the column, after every move they make.
A scan sees buttons with names, columns with headings and lists of cards, and all of it is valid. It never presses Move to Done, so it never sees the card move, and nothing in the markup says the counts report a result. EaseWeb's audit reports a list of draggable items that can all be moved without dragging as a lead to test by hand, when the page has no live region or when the list sits inside one. Asked to make the moves heard, AI assistants often put aria-live="polite" on the whole board or on each column. A screen reader then reads whatever text was added: the moved card's title and its buttons, and the two new counts as bare numbers, with no word for the column. With aria-atomic="true" added, it reads each changed region in full after each move: the whole board, or both columns, card by card. Only moving a card with a screen reader running shows what is said.
Try it
Press “Move to Done” on “Write release notes”, and listen. Then drag a card to another column.
The panel shows what a screen reader says. After each move, does anything say where the card went?
Broken Can you fix this?
To do 2
- Write release notes
- Update the pricing page
Doing 1
Done 0
Screen reader says:
(press a Move button, or drag a card)
The fix
Write where the card went into a status region that was on the page before the move.
- 1Keep one status region on the page from the start, outside the board.
- 2After every move, made any way, say the card and its new column, once.
- 3Never make the board, a column or a card list a live region.
<section class="column" data-column="todo"> <h2>To do <span class="count">2</span></h2> <ul> <li data-card="notes" draggable="true"> <span id="card-notes">Write release notes</span> <button type="button" data-to="doing" aria-describedby="card-notes">Move to Doing</button> <button type="button" data-to="done" aria-describedby="card-notes">Move to Done</button> </li> … </ul></section><!-- Doing and Done are the same: a heading with its count over a list of cards -->A move line under the board
<section class="column" data-column="todo"> <h2>To do <span class="count">2</span></h2> <ul> <li data-card="notes" draggable="true"> <span id="card-notes">Write release notes</span> <button type="button" data-to="doing" aria-describedby="card-notes">Move to Doing</button> <button type="button" data-to="done" aria-describedby="card-notes">Move to Done</button> </li> … </ul></section><!-- Doing and Done are the same: a heading with its count over a list of cards --><p id="board-status" role="status" class="board-status"></p>The card moves, the counts change and focus follows the card, but none of it is in a live region, so a screen reader has only the focused button to read.
The p with role="status" is in the HTML from the start, empty and outside the columns, so the browser is already watching it when the first move writes into it. After a press of Move to Done, a screen reader reads the newly focused button, then "Write release notes moved to Done." The sentence names the card and the column in the words on screen, and nothing else on the board is read. The drop of a drag calls the same function, so a move made with the mouse is announced in the same words. The line also shows sighted users the last move, which helps when a card has jumped out of view on a long board.
Both announce every move without the message needing focus, and they share the same code. The line under the board also tells sighted users what just happened, and gives a later Undo or an error a place to appear; choose it when the design has room for it. The hidden region leaves the board as drawn, for a design or a theme you can't change, and one region can serve every board and list on the site, as long as each message names its item and where it went.
One message, every way of moving. Write the sentence in the one function that moves a card, and call it from every way in: the move buttons, a Move to list, keyboard dragging and the drop of a mouse drag. A board whose buttons are announced but whose drops are silent leaves out screen reader users who drag, and people who use a magnifier with speech.
What to say. Name the card and its new column in the words on screen: "Write release notes moved to Done." Add its position only when the move chose one or the column is sorted ("moved to Done, 2 of 3"). Don't read out the board's new state, the counts or the card's details; people who want them can read the column. A move the server refuses, or one a column's card limit blocks, needs words too: "Write release notes could not be moved. It is still in To do."
Focus first, then the message. Move focus to the card, then write the sentence. A polite message is meant to wait until the screen reader has finished reading the newly focused button. Written before the focus moves, it can be cut short by the reading of the new focus. Drag-and-drop boards that only a mouse can use covers where focus should go after a move.
Not during the drag. Say nothing while a card travels under the mouse; announce where it lands. Keyboard dragging is different, because a screen reader user can't see where the card is: there, each step is announced as it happens ("picked up", "over Doing", "dropped in Done", "put back in To do"), as the drag-and-drop guide's keyboard dragging does.
Not a fix: the board as a live region. Putting aria-live or role="status" on the board, a column or a list makes the screen reader read the content that changed, not the meaning of the change. Without aria-atomic, that is the added card's title and buttons and the counts as bare numbers; with it, the whole region, every card on the board or in both columns, after every move. The message is lost in the reading, or missing from it.
The region must exist first. Render the region once, outside any column component, keyed list or {#if} that the move redraws. A region that arrives along with its message is usually not announced; status messages that are shown but never announced shows that failure in full.
Drag libraries. Some drag and drop libraries keep a live region of their own and announce drags by default. Check the words they use: dnd-kit's default messages, for example, name items and drop areas by their ids, so give it messages with the card's title and the column's name. Use either the library's region or your own for a move, not both, or every move is said twice.
Politeness. role="status" waits for the screen reader to finish, which suits a move. Don't use role="alert" or aria-live="assertive"; it can cut into the reading of the new focus.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
4 checks.
Test with: Screen reader, Keyboard, Mouse
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the board component or its drag library changes.
Limits
Live regions behave differently across screen readers and browsers, and their timing beside a focus change differs most. This pattern covers moving a card between columns on one board. Making a card movable without dragging is covered in drag-and-drop boards that only a mouse can use, and reordering items within one list, with their new position said, in sortable lists that move only by dragging, or in silence. Status messages in general are covered in status messages that are shown but never announced. Test your real board, with its drag library, its card limits and its narrow layout, with the screen readers your users use.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.