---
title: "Make sortable columns buttons · Agent Wranglers"
url: https://agentwranglers.se/playbook/app-ui/lists-and-tables/sortable-headers
updated: 2026-10-20
licence: "All rights reserved"
---

# Make sortable columns buttons

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Lists and tables](https://agentwranglers.se/playbook/app-ui/lists-and-tables)
- Rule: Put a button inside each sortable column header, and set `aria-sort` on the header of the sorted column only.
- How: Start from [table headers](https://agentwranglers.se/playbook/website/accessibility/data-tables). The button's name is the column name. Set `aria-sort="ascending"` or `"descending"` on the sorted `th` and remove it from the others. Show the direction with an icon as well as the attribute. Announce the new order in a [status region](https://agentwranglers.se/playbook/website/accessibility/status-messages), such as "Sorted by amount, highest first".
- Check: A browser test tabs to a header button and presses Enter. That header has `aria-sort`, no other header has it, and the status region names the order.

Example:

```html
<th scope="col" aria-sort="descending">
  <button type="button" data-sort="amount">Amount <svg aria-hidden="true" class="sort-icon">…</svg></button>
</th>
<th scope="col"><button type="button" data-sort="customer">Customer</button></th>
```

```ts
export function markSorted(table: HTMLTableElement, column: string, direction: 'ascending' | 'descending') {
  for (const header of table.querySelectorAll('th')) header.removeAttribute('aria-sort');
  table.querySelector(`button[data-sort="${column}"]`)?.closest('th')?.setAttribute('aria-sort', direction);
}
```

```python
from playwright.sync_api import expect

def test_sort_by_keyboard(page):
    page.goto("https://staging.example.com/orders")
    page.get_by_role("button", name="Amount").focus()
    page.keyboard.press("Enter")
    expect(page.locator("th[aria-sort]")).to_have_count(1)
    expect(page.get_by_role("columnheader", name="Amount")).to_have_attribute("aria-sort", "ascending")
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/lists-and-tables/sortable-headers`.

- Previous: [Sort and filter on the server](https://agentwranglers.se/playbook/app-ui/lists-and-tables/server-sort-and-filter)
- Next: [Use grid keys only for editable grids](https://agentwranglers.se/playbook/app-ui/lists-and-tables/grid-keyboard)
- [Lists and tables](https://agentwranglers.se/playbook/app-ui/lists-and-tables)
