Skip to content
easeweb
Search topics

Sortable lists that move only by dragging, or in silence

A ranked list can be reordered only by dragging its rows by their grips, or its Move up and Move down buttons move a row without a word about where it went.

WCAG 2.2
SC 2.1.1ASC 2.5.7AA· new in 2.2SC 4.1.3AA· new in 2.1
Required by
Section 508 · EN 301 549 (EU)
Broken <li draggable="true">
The accessibility problem illustrated: Motor:How do I move this up?
01

The problem

People who can't drag can't change the order at all, and screen reader users who move a row with a button can't tell where it went.

02

Try it

Put “Delivery speed” first. Drag it, then put the mouse aside and try with Tab.

The panel shows what a screen reader says. In Broken 1, can you move a row without dragging? In Broken 2, press Move up: does anything say where the row went?

Broken Can you fix this?

Rank what matters most when you order

  1. Price
  2. Delivery speed
  3. Easy returns
  4. Reviews

Screen reader says:

(Tab to a row, or drag one)

A recreated demo. The broken version is intentionally inaccessible.

03

The fix

Keep the drag, add controls that move each row with a press, and say every row's new position in a status region.

  1. 1Every row moves up and down with single clicks, taps or key presses, no dragging.
  2. 2Every move says the item and its new position, once, without moving focus.
  3. 3Dragging stays as a shortcut, never as the only way to change the order.
Before

Rows that move only by dragging

<h2 id="rank-title">Rank what matters most when you order</h2><ol id="ranking" aria-labelledby="rank-title">  <li draggable="true" data-item="speed">    <svg class="grip" aria-hidden="true">…</svg>    <span id="item-speed">Delivery speed</span>  </li>  …</ol>
After

Move up and Move down, with each move said

<h2 id="rank-title">Rank what matters most when you order</h2><ol id="ranking" aria-labelledby="rank-title">  <li draggable="true" data-item="speed">    <svg class="grip" aria-hidden="true">…</svg>    <span id="item-speed">Delivery speed</span>    <button type="button" data-move="-1" aria-describedby="item-speed">Move up</button>    <button type="button" data-move="1" aria-describedby="item-speed">Move down</button>  </li>  …</ol><p id="rank-status" role="status"></p>

Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.

04

Design ideas

A ranking can look calm and still move without a drag.

Six ways to draw the same ranking. Try each with clicks, then put the mouse aside and use Tab: four move a row with single presses and say where it went, and two move only under a held pointer.

In the design file

  • Draw every row’s move control at rest, not only on hover or after a long press.
  • Draw the line that confirms a move under the list, such as “Delivery speed moved to 1 of 3.”
  • Draw the ends of the list, with the top row’s Move up dimmed but still there, and what it says when pressed.
  • Draw each move control with its focus ring, and the menu or numbers it opens.
  • Draw the phone layout with every move control shown, each at least 24 by 24 pixels.

Passes

    1. Price
    2. Delivery speed
    3. Easy returns

    Grip that opens a move menu The six-dot grip stays where the design put it, but it is a 32px button: a click, a tap or Enter opens Move to top, Move up, Move down and Move to bottom, and a drag can still drag. At rest the list looks exactly as drawn; the file needs the grip’s focus ring and the open menu.
    1. Price
    2. Delivery speed
    3. Easy returns

    Rank number you press to change The number at the start of each row is a 28px round button: press it and the places 1 to 3 open beside it, so any row reaches any place in two presses. It suits a ranking question, where the number is the answer people care about, and adds nothing at the row’s end.
  • Tap in order, most important first.

    Tap in order of importance No list to rearrange at all: people tap the options in the order that matters, and each takes a numbered badge; a second tap takes it out again. Every step is one press on a 44px-tall pill, it works the same on a phone, and the line under the options says the place each one was given.
    1. Price
    2. Delivery speed
    3. Easy returns

    A pair of small arrows on each row Two 28 by 28 pixel chevrons stacked at the end of each row, quieter than buttons with words. Since they show no words, their names start with what they do, “Move up: Delivery speed”, which voice control users can say. The top row’s up arrow is dimmed but stays, and says the row is already first.

Fails

    1. Price
    2. Delivery speed
    3. Easy returns
    Grip that appears on hoverWCAG 2.5.7 The calmest list of all: the grip fades in only when a row is pointed at, and dragging it is the only way to move the row. Tab finds nothing to press and a phone never shows the grip; draw it as a button that opens a menu, as the grip with a move menu does.
  • Press and hold a row to move it.

    1. Price
    2. Delivery speed
    3. Easy returns
    Press and hold to liftWCAG 2.5.7 Familiar from phone apps: hold a row for half a second until it lifts, then drag it into place. The hold and the drag are the only way to move it, so keyboard, switch and voice control users can’t, and nothing on the row says it can be done at all.
05

Verify the fix

5 checks.

Test with: Keyboard, Mouse, Touch, Screen reader

0 of 5 checked

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the list component or its drag library changes.

Limits

This is a starting pattern, not a guarantee for every application. Nested lists, trees whose items can change level and lists that load more items as they scroll have their own needs, and are not covered here. Sortable libraries differ in how they handle focus, keys and announcements: test the complete journey with the assistive technology 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.

How retests work