Sorting Tables
title: "Sorting Tables — Using aria-sort for Sortable Columns" description: "Learn how to use aria-sort to indicate sorted columns in data tables, allowing screen reader users to understand the current sort state." weight: 8 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, tables]
aria-sort tells screen readers which column is sorted and in what direction, essential for sortable data tables.
## What You'll Learn
How to add aria-sort values (ascending, descending, none, other) to sortable table headers and update them dynamically.
## Why It Matters
Without aria-sort, screen reader users see the visual sort indicator but cannot programmatically determine the sort state.
## Real-World Use
A user sorts a product table by price. The header cell has aria-sort="ascending". The screen reader announces "Price, ascending, sort button." The user knows the cheapest products are at the top.
## aria-sort Implementation
```html
<table>
<caption>Product inventory</caption>
<thead>
<tr>
<th scope="col" aria-sort="none">
<button onclick="sortTable('name')">Product Name</button>
</th>
<th scope="col" aria-sort="ascending">
<button onclick="sortTable('price')">Price</button>
</th>
<th scope="col" aria-sort="none">
<button onclick="sortTable('stock')">Stock</button>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>Widget A</td>
<td>$9.99</td>
<td>42</td>
</tr>
</tbody>
</table>
JavaScript Sorting
let sortState = { column: 'price', direction: 'ascending' };
function sortTable(column) {
// Reset all headers
document.querySelectorAll('[aria-sort]').forEach(th => {
th.setAttribute('aria-sort', 'none');
});
// Set new sort
const header = document.querySelector(`[onclick*="${column}"]`).closest('th');
if (sortState.column === column) {
sortState.direction = sortState.direction === 'ascending' ? 'descending' : 'ascending';
} else {
sortState.column = column;
sortState.direction = 'ascending';
}
header.setAttribute('aria-sort', sortState.direction);
// Perform actual sort
const tbody = document.querySelector('tbody');
const rows = Array.from(tbody.querySelectorAll('tr'));
const columnIndex = Array.from(header.parentElement.children).indexOf(header);
rows.sort((a, b) => {
const aVal = a.children[columnIndex].textContent;
const bVal = b.children[columnIndex].textContent;
if (sortState.direction === 'ascending') {
return aVal.localeCompare(bVal, undefined, { numeric: true });
}
return bVal.localeCompare(aVal, undefined, { numeric: true });
});
rows.forEach(row => tbody.appendChild(row));
}
Common Mistakes
1. aria-sort on wrong element
Put aria-sort on the th element, not on the button inside.
2. Not resetting other headers
When sorting by a new column, reset other headers to aria-sort="none".
3. No sort direction toggle
Users expect clicking the same column to toggle between ascending and descending.
4. Visual sort indicator missing
aria-sort alone is not enough. Provide a visible indicator (arrow icon) for sighted users.
5. Sort breaks keyboard navigation
The sort buttons must remain focusable and operable via keyboard.
Practice Questions
1. What are the valid aria-sort values? ascending, descending, none, and other.
2. What element should have aria-sort? The th element of the sorted column.
3. What should happen when a user clicks an already-sorted column? The sort direction should toggle between ascending and descending.
Challenge: Build a sortable table with three columns. Implement aria-sort updates, visual indicators, and keyboard support.
FAQ
Mini Project
Create a sortable employee directory table with columns for Name, Department, Salary, and Start Date. Implement ascending/descending toggle with aria-sort.
What's Next
Learn about Responsive Tables and how to make data tables usable on mobile devices.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro