A11y Patterns
All patterns

Table

A data table component with semantic headers and sort state

Related WCAG criteria — click to view details

Code example

Baseline (React)tsx
Loading...

Common baseline

Applies to all design systems
Must4
  • Provide a label for the table

    Provide a label via aria-label or aria-labelledby on the table. Screen reader users must be able to identify what data the table contains.

  • scope attribute on th elements

    Use scope="col" or scope="row" on th elements to indicate which direction the header represents.

  • id/headers connection for complex tables

    For complex tables with nested row/column headers, assign id to th and connect via the headers attribute on td.

  • Maintain th/td semantics

    Header cells must use th and data cells must use td so screen readers can correctly convey row/column relationships.

Should3
  • Provide description with caption element

    Add a caption element directly below the table element to describe the table purpose. It can be visually hidden but still conveys information to screen readers.

  • aria-sort on sortable columns

    Set aria-sort="ascending" or aria-sort="descending" on sortable column headers, and place the sort button inside the th.

  • Provide description for empty cells

    Empty td cells should have screen reader text (e.g., "Not applicable") via sr-only text, even if visually empty.

Avoid3
  • Using table for layout

    Do not use table for layout purposes. If it is a layout table, add role="presentation" so screen readers do not interpret it as a data table.

  • Using only td without th

    Using only td cells without th makes it impossible for screen readers to determine row/column relationships. Always use th for header rows and columns.

  • Recreating table with nested divs

    Unless you need complex interaction requiring role="grid", do not recreate a semantic table using divs.

Design system implementations

Additional checks

  • TableCell in TableHead auto-renders as th

    MUI TableCell inside TableHead automatically renders as <th>. The scope attribute must be added manually.

  • Convey table purpose with aria-label

    Add aria-label to the Table component to convey the table purpose to screen reader users.

  • Use TableSortLabel for sort state

    Using TableSortLabel automatically sets aria-sort, conveying the sort state to screen readers.

Code sample

MUI Tabletsx
Loading...

Implementation notes

  • MUI TableCell inside TableHead automatically renders as <th>.
  • TableContainer provides horizontal scrolling for wide tables.
  • TableSortLabel creates sortable column headers with automatic aria-sort.
  • Use component="th" scope="row" to explicitly set row headers.

References