Back to Learn Hub
Comprehensive Guide

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

Problem: Screen readers see this as random text, not a table structure!
Name
Role
Department
Alice Johnson
Frontend Developer
Engineering
Bob Smith
Product Manager
Product
Carol Williams
UX Designer
Design

❌ 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

ElementPurposeScreen Reader Benefit
<table>Container for tabular dataAnnounces "Table with X rows, Y columns"
<caption>Title/description of the tableRead first, gives users context before navigating
<thead>Groups header rowsDistinguishes headers from data rows
<th scope="col">Column header cellRead with each cell in that column
<th scope="row">Row header cellRead with each cell in that row
<tbody>Groups data rowsSeparates data from headers and footers
Pro Tip: Visually Hidden Captions
If you don't want a visible caption, use 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 criterionLevelWhat it requires here
1.3.1 Info and RelationshipsAHeader 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, ValueASort 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 MessagesAASorting, selection counts, and save or cancel results are announced through a live region because the change happens away from focus.
2.1.1 KeyboardASort, 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 ColorASort direction and selected rows are shown by an icon or text plus aria state, never by colour alone.
1.4.10 ReflowAAData 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 InstructionsAEvery 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 VisibleAAButtons inside header cells, checkboxes, and edit inputs all show a visible focus indicator within the dense grid.
2.4.3 Focus OrderAEntering edit mode moves focus to the input; saving or cancelling returns it to the control that started the edit.

Expected Keyboard Interaction

Keyboard interaction for the data table demos
KeyExpected result
TabMoves 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 SpaceActivates a sort button (cycling ascending, descending, unsorted), toggles a checkbox, or starts an edit.
Enter in an edit fieldSaves the value and returns focus to the Edit button.
Escape in an edit fieldCancels the edit and returns focus to the Edit button.
Arrow keys in the scroll regionScroll the table horizontally once the wrapper has focus.
Screen reader table commandsMove 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

  1. 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.
  2. 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.
  3. 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.