Accessible Data Tables
Master every aspect of building tables that work for everyone
Semantic HTML Tables
The foundation of accessible tables is using native HTML elements. Screen readers rely on semantic markup to understand table structure, announce row/column counts, and enable navigation between cells.
Screen Reader Navigation
Users can navigate between cells using arrow keys, jump to headers, and understand relationships between data.
Keyboard Accessibility
Native table elements support keyboard navigation out of the box, with no JavaScript required.
Proper Announcements
Screen readers announce "Table with 5 rows and 4 columns" and read column headers with each cell.
Try It Yourself
❌ VoiceOver reads: "Alice Johnson, Frontend Developer, Engineering" — no context about columns!
Don't: "Div Soup" Tables
<!-- ❌ INACCESSIBLE -->
<div class="table">
<div class="row header">
<div class="cell">Name</div>
<div class="cell">Role</div>
</div>
<div class="row">
<div class="cell">Alice</div>
<div class="cell">Developer</div>
</div>
</div>
<!-- Screen reader has NO idea this is tabular data -->Do: Semantic HTML
<!-- ✅ ACCESSIBLE -->
<table>
<caption>Employee Directory</caption>
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Role</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alice</td>
<td>Developer</td>
</tr>
</tbody>
</table>Essential Table Elements
| Element | Purpose | Screen Reader Benefit |
|---|---|---|
| <table> | Container for tabular data | Announces "Table with X rows, Y columns" |
| <caption> | Title/description of the table | Read first, gives users context before navigating |
| <thead> | Groups header rows | Distinguishes headers from data rows |
| <th scope="col"> | Column header cell | Read with each cell in that column |
| <th scope="row"> | Row header cell | Read with each cell in that row |
| <tbody> | Groups data rows | Separates data from headers and footers |
className="sr-only" to hide it visually while keeping it accessible. Never skip the caption—it's crucial for screen reader users to understand what the table contains.Understanding the Data Table Pattern
A data table lays records out in rows and columns where the header cells give meaning to every data cell. Screen readers depend on that structure: as the user moves from cell to cell, the software reads the column and row headers alongside the value, which is how someone who cannot see the grid answers "which column is this?". When the grid is built from divs, that relationship is gone and the table becomes a run of unrelated words.
The demos above cover the five situations that come up in real products: a plain table with a caption and <th scope> headers; sortable columns where the header contains a real button and the <th> carries aria-sort; two responsive strategies, a focusable horizontal-scroll region and a stacked card layout built on a definition list; row selection with named checkboxes and an indeterminate select-all; and inline editing that moves focus into the input and back to the Edit button afterwards. Each demo pairs the working version with a live region that announces what changed.
WCAG 2.2 Success Criteria Involved
| Success criterion | Level | What it requires here |
|---|---|---|
| 1.3.1 Info and Relationships | A | Header cells are th elements with scope, the table has a caption, and complex tables use headers and id so every cell maps to its headers. |
| 4.1.2 Name, Role, Value | A | Sort controls are buttons with a name, aria-sort on the header reports the current direction, and checkboxes and edit fields have accessible names. |
| 4.1.3 Status Messages | AA | Sorting, selection counts, and save or cancel results are announced through a live region because the change happens away from focus. |
| 2.1.1 Keyboard | A | Sort, select, and edit are keyboard operable, and a horizontally scrolling wrapper is focusable so it can be scrolled without a mouse. |
| 1.4.1 Use of Color | A | Sort direction and selected rows are shown by an icon or text plus aria state, never by colour alone. |
| 1.4.10 Reflow | AA | Data tables are the named exception to reflow at 320 CSS pixels, but the wrapper must scroll in two dimensions without hiding cells or dropping headers. |
| 3.3.2 Labels or Instructions | A | Every row checkbox has a label naming the row, such as 'Select Alice Johnson', and the edit field is labelled with what is being edited. |
| 2.4.7 Focus Visible | AA | Buttons inside header cells, checkboxes, and edit inputs all show a visible focus indicator within the dense grid. |
| 2.4.3 Focus Order | A | Entering edit mode moves focus to the input; saving or cancelling returns it to the control that started the edit. |
Expected Keyboard Interaction
| Key | Expected result |
|---|---|
| Tab | Moves between the interactive parts of the table: sort buttons, checkboxes, Edit buttons, and the scroll region. Plain data cells are not tab stops. |
| Enter or Space | Activates a sort button (cycling ascending, descending, unsorted), toggles a checkbox, or starts an edit. |
| Enter in an edit field | Saves the value and returns focus to the Edit button. |
| Escape in an edit field | Cancels the edit and returns focus to the Edit button. |
| Arrow keys in the scroll region | Scroll the table horizontally once the wrapper has focus. |
| Screen reader table commands | Move cell by cell with headers read aloud, for example Ctrl + Alt + arrows in NVDA and JAWS, or VO + arrows in VoiceOver. These come from the screen reader, not the page. |
The Failures We See Most Often
- Div soup and missing headers. A grid of divs, or a real table with td elements in the header row and no caption. Table navigation commands do nothing and no cell has context.
- Sort controls that are not controls. A click handler on the th, an arrow icon with no text, and no aria-sort. Keyboard users cannot sort and screen reader users cannot tell which column is sorted or in which direction.
- Responsive layouts that destroy the structure. Columns hidden on small screens, or cells restyled as blocks so the header association is lost. Scroll the intact table, or rebuild each row as a card with a definition list.
The accessible data tables guide covers complex headers, row and column groups, captions versus aria-label, and responsive strategies in depth. If your table needs arrow-key navigation between cells or editable cells everywhere, that is a data grid, a different widget with its own keyboard model; the accessible data grid guide explains where the line falls.