Skip to content

Table

C-17 · Components · Content

All elements · Table on the Components page

Last checked 2026-10-22 · Awaiting approval · Accessibility tests

Copies the bun run a11y:approve command for Table.

Table

C-17WCAG 2.2 AA · Passed #410
Axis Values
data-dense · data-striped · data-sticky-header flags
th[aria-sort] · __sort · __resize[data-state=resizing] column state
tr[data-state=selected] ([aria-selected] in a grid) · td[data-align=end] · [data-truncate] · __select · __actions · __footer parts
Sortable, selectable, resizable columns
Actions
INV-2026-0412.pdf Invoice jdJane Doe Approved £4,250.00 2h ago
Q3-statement-acme-holdings-final.xlsx Statement akAlex Kim In review £12,080.10 Yesterday
MSA-2026-draft-v4.docx Contract mrMaya Rossi Draft — 3 days ago

Guidance

When to use

  • Show records users compare across columns, such as name, type, owner, status, amount and date.
  • Let users sort by a column with the __sort header button and resize columns with __resize.
  • Select rows for bulk actions with a __select checkbox column and a select-all header, and report the count in __footer.
  • Keep headers on screen in a long table with data-sticky-header, and fit more rows with data-dense.
  • Show reference data, such as settings or audit entries, that users read rather than edit.

When to consider something else

  • When users edit cells, move by cell with the arrow keys, or scroll thousands of rows, use Data grid. See DataGrid.
  • When rows are a single line of text with a few trailing details, use List. See List.
  • When each item is visual or has a thumbnail, use Card. See Card.
  • When there are more rows than one screen, add Pagination below the table. See Pagination.

Usability

Do
  • Right-align numbers and dates with data-align="end" so values line up.
  • Truncate long file names with data-truncate and put the full value in a title or Tooltip.
  • Put row actions in a More Menu in the __actions column.
  • Set the select-all checkbox to indeterminate when some rows are selected.
  • Show an Empty state inside the table area when there are no rows or no results.
Don’t
  • Don't use a table for layout.
  • Don't hide columns users need on narrow screens without a way to show them.
  • Don't make the whole row clickable and also put checkboxes and menus inside it.
  • Don't use striping and dividers and dense rows all at once in a short table; pick what aids reading.

Accessibility

Keyboard

Table keyboard
Keys Action
Tab / Shift+Tab Moves through sort buttons, row checkboxes, links and row action buttons in reading order.
Enter or Space Activates the focused sort button; Space checks the focused row checkbox.
Arrow Left / Arrow Right Required for resizing: the binding must make __resize focusable (or offer a column menu) and let these keys change the width.

Roles and names

  • Use a native table with th scope="col" headers; give the table a name with a caption or aria-label.
  • The sorted column's th carries aria-sort="ascending" or "descending"; other sortable headers omit it. The sort control is a real button inside the th.
  • The actions column header holds visually hidden text (qf-sr-only "Actions") so it is not an empty header.
  • Row checkboxes need unique names built from the row, such as "Select INV-2026-0412.pdf"; select-all is "Select all rows".
  • aria-selected on tr is not supported by a plain table role; the checked checkbox is the accessible state. Use Data grid when rows need grid selection semantics.
  • Status Chips must carry the status in words.

Focus

  • Every interactive element is a Tab stop; with many rows, prefer Data grid's single Tab stop and arrow keys.
  • After sorting, keep focus on the sort button that was pressed.
  • After a row action deletes a row, move focus to the next row's first control.
  • A sticky header must not cover the focused row (2.4.11).

Other requirements

  • Announce sort changes and the __footer selection count with a polite live region (4.1.3).
  • Column resizing by drag needs a non-drag way, such as a column menu with Wider and Narrower (2.5.7); the 0.375rem resize strip is too small to be the only target (2.5.8).
  • Wide tables scroll inside .qf-table-wrap so the page does not scroll sideways at 320px (1.4.10); the wrapper needs tabindex="0" and a label so keyboard users can scroll it.
  • Zebra rows, the selected fill and header borders need 3:1 where they carry meaning (1.4.11); text needs 4.5:1 on every row tint (1.4.3).

Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.

Accessibility tests

WCAG 2.2 AA · Passed

Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.

Table test checklist
Area Automated A person checks
General Passed Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme.
Zoom Passed At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping.
Keyboard Passed Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (3 rows)
Screen reader Passed With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (6 items)

Approving. When the checklist passes on the checked run, record it with bun run a11y:approve -- table --by "Your name" and commit a11y/approvals.json with the rebuilt pages. All test status

Package

Consumers link one stylesheet, css/classic/index.css, which includes every element. The files below are where this element is defined.

Table package
Source css/classic/components/navigation.css
Specimens also use Avatar · Box · Button · Card · Chip · Icon · Text · Toggle · Toolbar
Sprites sprites/icons.svg
React Not yet available: the React binding has not started.

Latest updates

No recorded changes yet.

All release notes