C-17 · Components · Content
All elements · Table on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve Table
Approving as
| 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 |
| 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
__sortheader button and resize columns with__resize. -
Select rows for bulk actions with a
__selectcheckbox 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 withdata-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
- Right-align numbers and dates with
data-align="end"so values line up. -
Truncate long file names with
data-truncateand put the full value in atitleor Tooltip. - Put row actions in a More Menu in the
__actionscolumn. - 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 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
| 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
tablewithth scope="col"headers; give the table a name with acaptionoraria-label. -
The sorted column's
thcarriesaria-sort="ascending"or"descending"; other sortable headers omit it. The sort control is a realbuttoninside theth. -
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-selectedontris 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
__footerselection 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-wrapso the page does not scroll sideways at 320px (1.4.10); the wrapper needstabindex="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
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| 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.
Latest updates
No recorded changes yet.