Skip to content

Table

Tables present data in a systematic grid of columns and rows. Use tables for structured data that users need to scan, compare, or sort — never for layout.

When to use

  • Displaying tabular data (numbers, statuses, names, dates)
  • Comparing data across rows
  • Enabling sorting or selection of records

When not to use

  • Page layout — use CSS Grid or Flexbox
  • Key-value pairs with few fields — use a Structured List or description list
  • Navigation or action lists — use Card or list elements

Default

Borderless

Removes all row borders for a cleaner look in dense interfaces.

Zebra (striped)

Alternating row backgrounds for better readability in long tables.

Compact

Reduced padding for data-dense views like dashboards.

Sortable

Add data-sortable for vanilla JS behavior. Use aria-sort on the active <th> and .table__sort buttons.

Selectable

Add data-selectable for vanilla JS behavior. Use checkboxes with .table__select cells.

Responsive

Wrap in .table-wrapper--responsive to stack rows as cards on small screens. Add data-label to each <td>.

Key-value pairs?

For key-value displays (profiles, summaries, review pages), use Summary List instead of a table. Summary List uses <dl> semantics and supports actions and a card variant.


CSS classes

ClassDescription
.tableBase table class
.table--borderlessRemoves row borders
.table--zebraAlternating row backgrounds
.table--compactReduced padding
.table--extra-compactMinimal padding
.table__numRight-aligned numeric cell (th/td)
.table__sortSortable column header button
.table__sort--activeActive sort column
.table__sort-iconSort direction indicator
.table__selectCheckbox column cell
.table__row--selectedSelected row highlight
.table__footerTable footer with count/actions
.table__countTabular-nums count display
.table-wrapperOverflow container
.table-wrapper--responsiveEnables stacked mobile layout

Accessibility

  • Always provide a <caption> — use .sr-only if not visually needed
  • Use <th scope="col"> for column headers, <th scope="row"> for row headers
  • Use aria-sort="ascending" or aria-sort="descending" on the active sorted column
  • Sortable headers use <button> elements inside <th> for keyboard access
  • Selection checkboxes have descriptive aria-label attributes
  • In responsive mode, data-label on <td> provides context when headers are hidden

References