Reorder Lists
title: "Reorder Lists — Building Accessible Sortable Lists" description: "Learn how to build accessible reorderable lists with keyboard support, ARIA roles, and screen reader announcements for sorted items." weight: 8 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, drag-drop]
Accessible reorderable lists combine keyboard controls, ARIA roles, focus management, and screen reader announcements for sorting items.
## What You'll Learn
How to build a complete accessible sortable list component.
## Why It Matters
Sortable lists appear in todo apps, playlists, kanban boards, and settings. Inaccessible sort controls block users from organizing their content.
## Real-World Use
A user opens a grocery list app. They press the "Move Down" button on "Milk" to move it below "Eggs." The list reorders, focus stays on "Milk," and the screen reader announces "Milk moved to position 3."
## Complete Reorderable List
```html
<div role="region" aria-label="Grocery list">
<h2>Grocery List</h2>
<div id="reorder-status" role="status" aria-live="polite" aria-atomic="true"></div>
<ol role="list" aria-label="Grocery items" id="grocery-list">
<li role="listitem" tabindex="0"
aria-label="Item 1: Bread"
data-item="Bread">
<button aria-label="Move Bread up"
class="btn-up" onclick="reorder(this, -1)">Up</button>
<span class="item-text">Bread</span>
<button aria-label="Move Bread down"
class="btn-down" onclick="reorder(this, 1)">Down</button>
</li>
<li role="listitem" tabindex="0"
aria-label="Item 2: Eggs"
data-item="Eggs">
<button aria-label="Move Eggs up"
class="btn-up" onclick="reorder(this, -1)">Up</button>
<span class="item-text">Eggs</span>
<button aria-label="Move Eggs down"
class="btn-down" onclick="reorder(this, 1)">Down</button>
</li>
<li role="listitem" tabindex="0"
aria-label="Item 3: Milk"
data-item="Milk">
<button aria-label="Move Milk up"
class="btn-up" onclick="reorder(this, -1)">Up</button>
<span class="item-text">Milk</span>
<button aria-label="Move Milk down"
class="btn-down" onclick="reorder(this, 1)">Down</button>
</li>
</ol>
</div>
JavaScript
function reorder(button, direction) {
const item = button.closest('[role="listitem"]');
const list = item.parentElement;
const items = Array.from(list.children);
const index = items.indexOf(item);
const newIndex = index + direction;
if (newIndex < 0 || newIndex >= items.length) return;
if (direction < 0) {
list.insertBefore(item, items[newIndex]);
} else {
list.insertBefore(item, items[newIndex + 1]);
}
item.focus();
item.setAttribute('aria-label',
`Item ${newIndex + 1}: ${item.dataset.item}`);
updateLabels(items);
const status = document.getElementById('reorder-status');
status.textContent = `${item.dataset.item} moved to position ${newIndex + 1}`;
}
function updateLabels(items) {
items.forEach((item, i) => {
const name = item.dataset.item;
const btnUp = item.querySelector('.btn-up');
const btnDown = item.querySelector('.btn-down');
btnUp.setAttribute('aria-label', `Move ${name} up`);
btnDown.setAttribute('aria-label', `Move ${name} down`);
btnUp.disabled = i === 0;
btnDown.disabled = i === items.length - 1;
});
}
Common Mistakes
1. No role="list" or role="listitem"
Without explicit roles, screen readers may not recognize the list structure.
2. tabindex not on list items
List items need tabindex="0" so keyboard users can Tab to them.
3. Labels not updated after reorder
aria-label on items and buttons must reflect the new position after reorder.
4. Disabled buttons not handled at boundaries
The Move Up button on the first item and Move Down on the last must be disabled.
5. No status live region
Without a live region, screen readers do not announce the reorder result.
Practice Questions
1. What role should the list container have? role="list" for the container and role="listitem" for each item.
2. Why should aria-label be updated after reorder? To reflect the new position number so screen readers announce the correct position.
3. How do you handle boundary conditions? Disable the Move Up button on the first item and Move Down on the last.
Challenge: Extend the reorderable list to support keyboard shortcuts: Alt+ArrowUp and Alt+ArrowDown to move items.
FAQ
Mini Project
Build a complete reorderable grocery list with 10 items. Implement move buttons, boundary handling, label updates, and keyboard shortcuts.
What's Next
Learn about Drag Handle design for accessible drag-and-drop interfaces.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro