Role and semantics
Section titled “Role and semantics”- DataTable is a real
<table>element (built from the Table parts):<caption>,<th scope>and<td>. Its name comes fromcaption; the scroll region carries the same name and takes focus with Tab. - The
thof a sortable column hasaria-sort(ascending,descendingornone). A<button>sits inside the header; its name is the column name. The direction icon isaria-hiddenand visible;aria-sortreports the state. - Sorting and selection changes are announced in one polite live region (
role="status",aria-live="polite"): “Sorted by Name, ascending”, “Selected rows: 2”. While loading, the region says “Loading”. - Selection: a row does not carry
aria-selected, because that attribute is not valid on a plain table row. The selected state is given by the checkbox’s checked state anddata-selected. The select-all checkbox isaria-checked="mixed"while some rows are selected. - Row checkboxes carry the row’s name (
getRowLabel): “Select row Item 1”. Without a label the row id is used. - Loading: the table is
aria-busy="true"; the skeleton bars arearia-hidden. - The error message has
role="alert"and is announced at once. - With virtualisation the table has
aria-rowcount(total rows plus the header) and every row hasaria-rowindex, so screen readers hear the real size of the table. Padding rows arearia-hidden.
Keyboard
Section titled “Keyboard”| Key | Behaviour |
|---|---|
| Tab | In order: the scroll region, the column button, the sort buttons, the select-all checkbox, each row’s checkbox, the row open button and the row actions. |
| Enter, Space | Runs the sort button, the row open button and the action buttons; toggles a checkbox (Space). |
| Escape | Closes the column panel and returns focus to the button. |
| Arrow keys | Scroll the table while the scroll region has focus. |
There is no grid navigation (cell to cell with arrow keys); each interactive element is its own tab stop. This is deliberate: the table is a plain table, not a grid role.
Each interactive element has its own focus ring: the sort button, the row open button, the checkboxes, the action buttons and the scroll region (drawn inside the region). The ring is 2 px wide and 2 px away; it shows for keyboard focus only. When the column panel closes, focus returns to the button.
Screen reader output
Section titled “Screen reader output”| Example | Read |
|---|---|
| Table | “Item list, table, 6 rows, 5 columns” |
| Sortable header | “Name, column header, sorted ascending; Name, button” |
| Select all | “Select all rows, checkbox, mixed” |
| Row checkbox | “Select row Item 1, checkbox, checked” |
| Live region | “Sorted by Name, ascending” |
| Loading | “Loading” |
| Expand button | “Show details of Item 1, button, collapsed”; aria-controls points to the detail cell |
Contrast
Section titled “Contrast”The values are the same as for Table; text is at least 4.5:1 in every brand and mode.
| Pair | Light mode | Dark mode |
|---|---|---|
color-text-default / table-row-background-hovered |
15.44:1 | 13.49:1 |
color-text-default / table-row-background-selected (lowest) |
15.04:1 | 13.98:1 |
color-text-subtle (header) / table-header-background |
8.38:1 | 9.23:1 |
color-focus-ring / color-surface-default (lowest) |
5.97:1 | 8.09:1 |
The skeleton bars are decorative and carry no text. The sort icon sits next to text; it never carries information alone.
WCAG 2.2
Section titled “WCAG 2.2”| Criterion | How DataTable meets it | What the product team does |
|---|---|---|
| 1.3.1 Info and relationships | A real table, scope, aria-sort, aria-rowcount. |
Make the first column a rowHeader; provide getRowLabel. |
| 1.4.1 Use of colour | Selection through the checkbox and data-selected; sorting through the arrow and aria-sort. |
Give row state as text with a StatusBadge. |
| 1.4.3 Contrast (minimum) | At least 8.38:1 (secondary) and 13.49:1 (default). | Do not give cells custom colours. |
| 2.1.1 Keyboard | Every function works with Tab, Enter, Space and Escape. | Do not open a row with onClick alone; use onRowOpen. |
| 2.4.3 Focus order | Focus follows the visual order; it returns to the button when the panel closes. | Do not put many items in the actions column. |
| 2.4.7 Focus visible | The ring is on every interactive element. | Do not remove outline with className. |
| 2.5.8 Target size | Checkboxes, sort and action buttons are at least 24 px (IconButton sm is 32 px). |
Keep 24 px when you put your own controls in cells. |
| 4.1.2 Name, role, value | Buttons have a name; checkboxes have a name and a state. | Put the row in the name of action buttons. |
| 4.1.3 Status messages | Sorting, selection and loading in a polite live region; the error is an alert. |
Adapt messages to your product language with messages. |