skip to content
menu
components · data table

data table

A data table holds a list that people work through: they scan it, sort it, select rows and act on them, often with the keyboard alone.

actions
S05E18, 13 months agomissingnot searched yet
S05E17, 13 months agomissingnothing found · again in 6h
S05E16, 14 months agomissingnot searched yet
S05E15, 14 months agomissingnot searched yet
S05E14, 14 months agomissingnothing found · again in 6h
S05E13, 14 months agomissingnothing found · again in 6h
S05E12, 14 months agomissingnothing found · again in 6h
S05E11, 15 months agomissingfound a release
S05E10, 15 months agomissingnot searched yet
S05E09, 15 months agomissingfound a release
S05E08, 15 months agomissingnothing found · again in 6h
S05E07, 16 months agomissingnot searched yet
S05E06, 16 months agomissingnot searched yet
S05E05, 16 months agomissingnothing found · again in 6h
S05E04, 16 months agomissingnot searched yet
S05E03, 17 months agomissingnot searched yet
S05E02, 17 months agomissingnot searched yet
S05E01, 17 months agomissingnot searched yet
S04E22, 2 years agomissingnothing found · again in 6h
S04E21, 2 years agomissingfound a release
S04E20, 2 years agoon its waydownloaded
S04E19, 2 years agomissingnothing found · again in 6h
S04E18, 2 years agomissingnot searched yet
S04E17, 2 years agomissingnot searched yet
S04E16, 2 years agomissingnothing found · again in 6h
S04E15, 2 years agomissingnothing found · again in 6h
S04E14, 2 years agomissingnot searched yet
S04E13, 2 years agomissingnothing found · again in 6h
S04E12, 2 years agomissingnot searched yet
S04E11, 2 years agoon its waygrabbed
S04E10, 2 years agomissingsearch failed · again in 2h
S04E09, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E08, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E07, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E03, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E01, 2 years agomissingnot searched yet
0 selected

when to use

  • For a list people work through: they scan it, sort it, select rows and act on them. It is the heart of a worklist.
  • When rows need any of these: sorting by a column, selecting one row or many, grouping under a heading row, loading more rows a page at a time, or moving from row to row with the keyboard.
  • For long lists. Shown a page at a time, it stays quick with thousands of rows; the React page has the details.

when to use something else

  • For a short list of records that people only read. Use the plain table. It is simpler, and a screen reader has less to announce.
  • For the details of one record. A single row with many columns is hard to read. List the labels and values in a card instead.
  • For places to go. A set of apps or areas to open is a tile group, or the home page.
  • To pick values in a form. Use checkboxes or a multi select. Selecting rows is for acting on them, not for filling in a form.
  • When every column has to stay a column, however narrow the screen. The data table never scrolls sideways; it moves less important columns under each row instead. The plain table keeps all its columns and scrolls inside its frame.

anatomy

  1. Frame. A thin border around the whole table, as wide as its container. The table never scrolls sideways, so its header can stick to the top of the page.
  2. Header row. A short label for each column, on one line. It stays at the top while the rows scroll underneath, as a sticky header.
  3. Sort button. In a column that can be sorted, the label is a button with a small double arrow beside it. The direction the column is sorted in is drawn in full, the other one faded.
  4. Selection column. A narrow column of checkboxes: one in the header for every visible row, and one in each row.
  5. Group row. A heading row across the whole table for the rows of one group. It holds an arrow that shows whether the group is open, the group's name, and an action for the group at its end.
  6. Data row. The cells of one item, with a thin rule below. A row lightens under the pointer; a selected row is tinted blue and has a blue bar on its leading edge.
  7. Row header. The cell that names the row, usually the first one, in brighter text.
  8. Highlight. A bar in a state's colour on the leading edge of a row, for the few rows that need acting on. On a selected row it takes the place of the blue bar.
  9. Pop-ins. On a narrow table, the labels and values of the columns that made room, under the row's name.
  10. Empty cell. When there are no rows, one cell across the whole table holds the empty state.
  11. Show more. Under a long list: how many rows are shown out of how many, and a small button to show the next page.
  12. Progress line. While the table loads, a thin blue line moves along its top edge.

variants and states

sorting

People sort the table by clicking a column's label. Clicking the sorted column again turns the order around. Clicking another column sorts by that one, in its first direction: ascending, unless the column starts with the newest or largest first, as date columns usually do. There is no third click back to the unsorted order.

The sort is predictable. Rows that are equal keep the order they had. Text is compared the way people read it, so “E2” comes before “E10”, and capitals and accents make no difference. Dates are compared by time, and empty values always go last, whichever the direction.

In a grouped table, the rows stay in their groups, and the groups follow the order of their first row after sorting.

S04E12, 2 years agomissingnot searched yet
S04E11, 2 years agoon its waygrabbed
S04E10, 2 years agomissingsearch failed · again in 2h
S04E09, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E08, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E07, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E03, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E01, 2 years agomissingnot searched yet

selection

When rows can be selected, the table gets a column of checkboxes. When to offer selection, and how a selection meets the actions above it, is described in selection and bulk actions. This is what the table itself does:

  • People select a row with its checkbox, by clicking the row (unless clicking opens it), or with space on the row that has focus. shift selects a range, and ctrl + a (or cmd + a) selects every visible row. Behaviour, below, has the details.
  • The checkbox in the header stands for every visible row: the rows on the screen, not those inside closed groups or beyond “show more”. It is ticked when every visible row that can be selected is selected, and shows the mixed state when only some of them are. Pressing it while it is ticked clears the whole selection, hidden rows included. It is disabled when no visible row can be selected. Offering “select all 2,500” is the job of the selection toolbar, not of this checkbox.
  • A row that can't be selected has a disabled checkbox, and clicks, ranges, select-all and the keyboard all leave it out. Its status says why; see rows that can't be selected.
S04E12, 2 years agomissingnot searched yet
S04E11, 2 years agoon its waygrabbed
S04E10, 2 years agomissingsearch failed · again in 2h
S04E09, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E08, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E07, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E03, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E01, 2 years agomissingnot searched yet

grouping

Rows that belong together can sit under a group row. Its label says what the group is and how many rows it holds, such as “The Quiet Harbour · S04 · 8 missing”, and keeps the name's own capitals.

A group row can carry one action at its end, a small quiet button that acts on the whole group, such as “grab all 8”. Pressing that button doesn't open or close the group.

A group opens and closes with a click on its row, with enter or space, or with the left and right arrow keys.

The Quiet Harbour · S06 · 22 missing
S06E22, 6 days agoon its waydownloaded
S06E21, 13 days agomissingnot searched yet
S06E20, 3 weeks agoerror: needs attentionno release passed the quality profile: every one was below 720p
S06E19, 4 weeks agomissingfound a release
S06E18, 5 weeks agomissingfound a release
S06E17, 6 weeks agomissingnothing found · again in 6h
S06E16, 7 weeks agomissingfound a release
S06E15, 8 weeks agomissingnot searched yet
S06E14, 2 months agomissingnothing found · again in 6h
S06E13, 2 months agomissingfound a release
S06E12, 2 months agomissingnothing found · again in 6h
S06E11, 3 months agomissingnot searched yet
S06E10, 3 months agomissingsearch failed · again in 2h
S06E09, 3 months agomissingnothing found · again in 6h
S06E08, 3 months agomissingnot searched yet
S06E07, 4 months agomissingnot searched yet
S06E06, 4 months agomissingfound a release
S06E05, 4 months agomissingnothing found · again in 6h
S06E04, 4 months agomissingnothing found · again in 6h
S06E03, 5 months agomissingnothing found · again in 6h
S06E02, 5 months agomissingnot searched yet
S06E01, 5 months agomissingnot searched yet
Lunar Meridian · S05 · 8 missing
S05E08, 5 months agomissingnot searched yet
S05E07, 6 months agomissingnothing found · again in 6h
S05E06, 6 months agomissingnot searched yet
S05E05, 6 months agomissingnothing found · again in 6h
S05E04, 6 months agomissingnothing found · again in 6h
S05E03, 7 months agomissingnot searched yet
S05E02, 7 months agomissingnothing found · again in 6h
S05E01, 7 months agoon its wayqueued for a search and grab
The Quiet Harbour · S05 · 22 missing
S05E22, 12 months agomissingnot searched yet
S05E21, 12 months agomissingfound a release
S05E20, 13 months agomissingfound a release
S05E19, 13 months agomissingnot searched yet
S05E18, 13 months agomissingnot searched yet
S05E17, 13 months agomissingnothing found · again in 6h
S05E16, 14 months agomissingnot searched yet
S05E15, 14 months agomissingnot searched yet
S05E14, 14 months agomissingnothing found · again in 6h
S05E13, 14 months agomissingnothing found · again in 6h
S05E12, 14 months agomissingnothing found · again in 6h
S05E11, 15 months agomissingfound a release
S05E10, 15 months agomissingnot searched yet
S05E09, 15 months agomissingfound a release
S05E08, 15 months agomissingnothing found · again in 6h
S05E07, 16 months agomissingnot searched yet
S05E06, 16 months agomissingnot searched yet
S05E05, 16 months agomissingnothing found · again in 6h
S05E04, 16 months agomissingnot searched yet
S05E03, 17 months agomissingnot searched yet
S05E02, 17 months agomissingnot searched yet
S05E01, 17 months agomissingnot searched yet
The Copper Lantern · S03 · 7 missing
S03E07, 17 months agomissingnothing found · again in 6h
S03E06, 17 months agomissingnothing found · again in 6h
S03E05, 17 months agomissingnothing found · again in 6h
S03E04, 18 months agomissingnot searched yet
S03E03, 18 months agomissingnot searched yet
S03E02, 18 months agomissingnot searched yet
S03E01, 18 months agoon its waywaiting for the catalog
Lunar Meridian · S04 · 9 missing
S04E09, 17 months agomissingnot searched yet
S04E08, 18 months agomissingnot searched yet
S04E07, 18 months agomissingnothing found · again in 6h
S04E06, 18 months agomissingfound a release
S04E05, 18 months agomissingnot searched yet
S04E04, 19 months agomissingnot searched yet
S04E03, 19 months agomissingnot searched yet
S04E02, 19 months agomissingnot searched yet
S04E01, 19 months agomissingnothing found · again in 6h
Paper Engine · S05 · 8 missing
S05E08, 18 months agoon its wayqueued for a search and grab
S05E07, 18 months agomissingnot searched yet
S05E06, 18 months agomissingnot searched yet
S05E05, 18 months agomissingnothing found · again in 6h
S05E04, 19 months agoon its waygrabbed
S05E03, 19 months agomissingnothing found · again in 6h
S05E02, 19 months agomissingnothing found · again in 6h
S05E01, 19 months agomissingnot searched yet
The Quiet Harbour · S04 · 22 missing
S04E22, 2 years agomissingnothing found · again in 6h
S04E21, 2 years agomissingfound a release
S04E20, 2 years agoon its waydownloaded
S04E19, 2 years agomissingnothing found · again in 6h
S04E18, 2 years agomissingnot searched yet
S04E17, 2 years agomissingnot searched yet
S04E16, 2 years agomissingnothing found · again in 6h
S04E15, 2 years agomissingnothing found · again in 6h
S04E14, 2 years agomissingnot searched yet
S04E13, 2 years agomissingnothing found · again in 6h
S04E12, 2 years agomissingnot searched yet
S04E11, 2 years agoon its waygrabbed
S04E10, 2 years agomissingsearch failed · again in 2h
S04E09, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E08, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E07, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E03, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E01, 2 years agomissingnot searched yet
The Copper Lantern · S02 · 9 missing
S02E09, 2 years agomissingfound a release
S02E08, 2 years agomissingnot searched yet
S02E07, 2 years agomissingnothing found · again in 6h
S02E06, 2 years agomissingnot searched yet
S02E05, 2 years agomissingnot searched yet
S02E04, 2 years agomissingnothing found · again in 6h
S02E03, 2 years agomissingnot searched yet
S02E02, 3 years agomissingnot searched yet
S02E01, 3 years agomissingnot searched yet
Lunar Meridian · S03 · 9 missing
S03E09, 2 years agomissingfound a release
S03E08, 2 years agoon its waygrabbed
S03E07, 2 years agomissingnothing found · again in 6h
S03E06, 3 years agomissingnothing found · again in 6h
S03E05, 3 years agomissingnot searched yet
S03E04, 3 years agomissingnot searched yet
S03E03, 3 years agomissingnothing found · again in 6h
S03E02, 3 years agomissingnot searched yet
S03E01, 3 years agomissingnot searched yet
Paper Engine · S04 · 9 missing
S04E09, 2 years agoerror: needs attentionevery source that answered timed out
S04E08, 3 years agomissingnot searched yet
S04E07, 3 years agomissingnot searched yet
S04E06, 3 years agomissingnot searched yet
S04E05, 3 years agomissingnot searched yet
S04E04, 3 years agomissingnot searched yet
S04E03, 3 years agomissingnot searched yet
S04E02, 3 years agomissingnot searched yet
S04E01, 3 years agomissingsearch failed · again in 2h
The Copper Lantern · S01 · 9 missing
S01E09, 3 years agomissingnothing found · again in 6h
S01E08, 3 years agomissingfound a release
S01E07, 3 years agomissingnothing found · again in 6h
S01E06, 3 years agomissingnothing found · again in 6h
S01E05, 3 years agomissingnothing found · again in 6h
S01E04, 3 years agomissingnothing found · again in 6h
S01E03, 3 years agomissingnothing found · again in 6h
S01E02, 4 years agomissingnothing found · again in 6h
S01E01, 4 years agomissingnothing found · again in 6h
Lunar Meridian · S02 · 9 missing
S02E09, 3 years agomissingnothing found · again in 6h
S02E08, 3 years agomissingnot searched yet
S02E07, 3 years agomissingnothing found · again in 6h
S02E06, 4 years agomissingnot searched yet
S02E05, 4 years agomissingnothing found · again in 6h
S02E04, 4 years agomissingfound a release
S02E03, 4 years agomissingnothing found · again in 6h
S02E02, 4 years agomissingfound a release
S02E01, 4 years agomissingnot searched yet
Paper Engine · S03 · 8 missing
S03E08, 3 years agoon its waywaiting for the catalog
S03E07, 4 years agomissingnot searched yet
S03E06, 4 years agomissingfound a release
S03E05, 4 years agomissingfound a release
S03E04, 4 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S03E03, 4 years agomissingfound a release
S03E02, 4 years agomissingnot searched yet
S03E01, 4 years agomissingnot searched yet
Paper Engine · S02 · 9 missing
S02E09, 4 years agomissingnot searched yet
S02E08, 5 years agomissingnot searched yet
S02E07, 5 years agomissingnot searched yet
S02E06, 5 years agomissingnothing found · again in 6h
S02E05, 5 years agoon its waydownloaded
S02E04, 5 years agoon its waydownloaded
S02E03, 5 years agomissingsearch failed · again in 2h
S02E02, 5 years agomissingnot searched yet
S02E01, 5 years agomissingnothing found · again in 6h

showing more

A long list doesn't have to arrive all at once. The table can show one page of rows, say 100, with a “show 100 more” button underneath that adds as many again. For the last few rows it says how many are left, such as “show 37 more”, and once everything is shown, the button goes.

Beside the button, a count such as “100 of 2,500” says how many rows are shown, out of how many there are. A screen reader announces each new count.

Only data rows on the screen count as shown; group rows don't count at all. Rows inside a closed group count in the total but never as shown, so with groups closed the count can stop below the total, such as “2,380 of 2,500”, with no button left.

The number of rows shown only grows, until the view changes: a new filter or another tab can start it again at one page.

movies · 140 missing
The Silver Quarter (2024), todaymissingnothing found · again in 6h
Velvet Ledger (2025), 2 days agomissingnot searched yet
The Paper Meridian (2024), 7 days agomissingfound a release
The Glass Atlas (2026), 3 weeks agomissingnot searched yet
The Copper Archive (2022), 3 weeks agomissingnot searched yet
The Coastal Orchard (2020), 3 weeks agomissingnot searched yet
Restless Assembly (2021), 4 weeks agomissingfound a release
The Cedar Garden (2026), 6 weeks agomissingnothing found · again in 6h
Hollow Hearth (2023), 6 weeks agomissingnot searched yet
The Cedar Garden (2022), 6 weeks agomissingnothing found · again in 6h
The Glass Atlas (2026), 6 weeks agomissingnothing found · again in 6h
Velvet Ledger (2025), 6 weeks agomissingnot searched yet
The Coastal Orchard (2020), 8 weeks agomissingnothing found · again in 6h
The Winter Frontier (2020), 2 months agomissingnot searched yet
Lunar Circuit (2025), 2 months agomissingnothing found · again in 6h
The Amber Harbour (2022), 2 months agomissingfound a release
The Copper Archive (2026), 3 months agomissingnot searched yet
The Golden Compass (2022), 4 months agomissingnothing found · again in 6h
The Cedar Garden (2022), 4 months agomissingsearch failed · again in 2h
The Signal Ridge (2020), 4 months agomissingnot searched yet
The Coastal Orchard (2020), 4 months agomissingnothing found · again in 6h
The Paper Meridian (2024), 4 months agomissingsearch failed · again in 2h
Restless Assembly (2025), 5 months agomissingfound a release
The Coastal Orchard (2024), 5 months agomissingnothing found · again in 6h
The Golden Compass (2026), 5 months agomissingnot searched yet
The Amber Harbour (2026), 5 months agomissingnot searched yet
The Silver Quarter (2024), 5 months agomissingnot searched yet
Hollow Hearth (2019), 6 months agomissingnothing found · again in 6h
Iron Lantern (2019), 6 months agomissingnot searched yet
The Signal Ridge (2020), 7 months agomissingfound a release
Northern Bureau (2021), 7 months agomissingfound a release
The Paper Meridian (2020), 7 months agomissingfound a release
The Silver Quarter (2024), 8 months agomissingnothing found · again in 6h
Northern Bureau (2025), 8 months agomissingsearch failed · again in 2h
The Cedar Garden (2022), 8 months agomissingnot searched yet
Quiet Station (2019), 8 months agomissingnothing found · again in 6h
Restless Assembly (2025), 9 months agomissingnothing found · again in 6h
Restless Assembly (2021), 9 months agomissingfound a release
Northern Bureau (2025), 9 months agoerror: needs attentionthe download client refused the release: disk below the storage floor
Iron Lantern (2023), 9 months agomissingnot searched yet
Hidden Current (2019), 9 months agomissingnot searched yet
Hidden Current (2019), 10 months agomissingnothing found · again in 6h
Restless Assembly (2021), 10 months agomissingfound a release
The Golden Compass (2026), 10 months agomissingnot searched yet
The Winter Frontier (2020), 10 months agomissingnot searched yet
Lunar Circuit (2021), 10 months agoerror: needs attentionno release passed the quality profile: every one was below 720p
Distant Engine (2021), 10 months agomissingnot searched yet
The Signal Ridge (2024), 11 months agomissingnot searched yet
Quiet Station (2019), 11 months agomissingnothing found · again in 6h
Salt Valley (2019), 11 months agomissingfound a release
The Signal Ridge (2024), 11 months agomissingfound a release
Northern Bureau (2021), 11 months agomissingnot searched yet
Hollow Hearth (2019), 11 months agomissingfound a release
The Winter Frontier (2020), 11 months agomissingfound a release
Velvet Ledger (2021), 11 months agomissingnothing found · again in 6h
Iron Lantern (2023), 12 months agomissingsearch failed · again in 2h
Quiet Station (2023), 12 months agomissingnot searched yet
The Paper Meridian (2024), 12 months agomissingnot searched yet
Distant Engine (2025), 12 months agomissingfound a release
Quiet Station (2023), 13 months agomissingnot searched yet
Velvet Ledger (2021), 13 months agomissingnot searched yet
The Winter Frontier (2024), 13 months agomissingnothing found · again in 6h
The Glass Atlas (2022), 13 months agomissingfound a release
The Golden Compass (2026), 13 months agomissingnothing found · again in 6h
The Cedar Garden (2026), 13 months agomissingnot searched yet
Lunar Circuit (2021), 13 months agomissingnot searched yet
The Glass Atlas (2022), 14 months agomissingnothing found · again in 6h
Distant Engine (2025), 14 months agomissingfound a release
The Cedar Garden (2026), 14 months agomissingnot searched yet
The Copper Archive (2022), 14 months agoon its waydownloaded
The Golden Compass (2022), 14 months agoerror: needs attentionno release passed the quality profile: every one was below 720p
Quiet Station (2019), 14 months agomissingnot searched yet
Salt Valley (2023), 15 months agomissingnot searched yet
The Amber Harbour (2026), 15 months agomissingnothing found · again in 6h
Hollow Hearth (2023), 15 months agomissingnot searched yet
The Silver Quarter (2020), 15 months agomissingnot searched yet
Quiet Station (2023), 15 months agoerror: needs attentionevery source that answered timed out
Velvet Ledger (2025), 15 months agomissingnot searched yet
Hidden Current (2019), 16 months agomissingnot searched yet
Iron Lantern (2023), 16 months agoerror: needs attentionthe download client refused the release: disk below the storage floor
The Glass Atlas (2022), 16 months agomissingnot searched yet
Hollow Hearth (2023), 16 months agomissingnot searched yet
Salt Valley (2019), 16 months agomissingnot searched yet
Lunar Circuit (2025), 17 months agoerror: needs attentionevery source that answered timed out
Lunar Circuit (2021), 17 months agomissingfound a release
Northern Bureau (2025), 17 months agomissingfound a release
The Coastal Orchard (2024), 18 months agomissingnothing found · again in 6h
Northern Bureau (2021), 18 months agomissingnothing found · again in 6h
Hollow Hearth (2019), 18 months agomissingfound a release
The Copper Archive (2022), 18 months agomissingnot searched yet
The Paper Meridian (2020), 18 months agomissingnothing found · again in 6h
Restless Assembly (2021), 18 months agomissingnot searched yet
The Coastal Orchard (2024), 19 months agomissingnothing found · again in 6h
The Winter Frontier (2020), 19 months agomissingnothing found · again in 6h
Velvet Ledger (2021), 19 months agomissingnot searched yet
Distant Engine (2021), 20 months agomissingnot searched yet
The Glass Atlas (2022), 20 months agomissingnothing found · again in 6h
Iron Lantern (2019), 20 months agomissingsearch failed · again in 2h
The Copper Archive (2026), 20 months agomissingfound a release
Salt Valley (2023), 20 months agomissingnot searched yet
100 of 2,644

narrow tables

When a table gets narrow, there isn't room for every column. Instead of scrolling sideways, the table makes room: its less important columns leave, and their values pop in under each row's name, each with its label.

  • The table goes by its own width, not the screen's. A table in a narrow side panel pops in on a wide screen too.
  • Each column can be ranked as low, medium or high importance. Low columns pop in first, when the table gets narrow; medium columns follow when it gets narrower still. High columns, and columns without a rank, always stay, and the row header never pops in. The exact widths are in the specs.
  • A column that pops in disappears as a column: no label in the header, no cells. Its values move under the row's name.
  • Because the table never scrolls sideways, keep the high columns few enough to fit the narrowest screen you support.

Today: when the column the rows are sorted by pops in, its sort button goes with it. The rows stay in order, but nothing on the screen, and nothing a screen reader can find, says what they are sorted by.

S04E10, 2 years agomissingsearch failed · again in 2h
S04E09, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E08, 2 years agoerror: needs attentionno release passed the quality profile: every one was below 720p
S04E07, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E03, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E01, 2 years agomissingnot searched yet

rows that open

A whole row can be an action, usually opening the item's details. A click anywhere outside the row's own controls opens it, and so does enter on the row that has focus. The checkbox still selects, and so do space, and shift with space or the up and down arrow keys.

When rows don't open, a click on a row that can be selected selects it, and enter does nothing. How opening and selecting share one row is explained in press versus select.

Today: a row that opens looks just like any other, with no pointer cursor and no arrow, and nothing tells assistive technology that enter opens it. Put a link in the row header as well, so where the row leads is a real link people can find.

episodeairedstate
S04E01, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E03, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
opened: nothing yet · 0 selected

highlighted rows

A row can carry a state (error, warning, information, success or neutral) as a bar in that state's colour on its leading edge. The example at the top of this page highlights the rows that failed.

The bar is only decoration. It tells assistive technology nothing, and colour on its own never carries a state, so the row also says its state in words, in a status cell.

Use highlights for the few rows that need acting on, such as an error for what failed, rather than colouring every row by its state.

the sticky header

The header row sticks by default. While the rows scroll underneath, it stays at the top of the page, or at the top of a panel that scrolls on its own.

Below something else that sticks, such as an app bar or a toolbar, the header sticks just under it. In a worklist, the header sticks below the toolbar.

loading

While new rows load, a thin blue line runs along the table's top edge; with reduced motion it is a still line across the full width. The rows stay as they are, at full strength, and people can keep working with them.

  • Keep the old rows while the new ones load. Don't empty the table first.
  • Show the empty state only once you know the list is empty, not while it is still loading.
  • The line sits on the frame's top edge and doesn't stick with the header, so in a long list it can scroll out of view.
episodeairedstate
S04E01, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E03, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet
S04E06, 2 years agomissingnot searched yet

empty

With no rows, the table shows its empty state across the whole table. Which kind of empty state, and what it says, is described in empty states.

Without one, an empty table is a header row with nothing under it.

episodeairedstate

nothing missing

Every aired episode is in the library.

density

A dense table has less space around each cell, so more rows fit on the screen: useful for side panels and long lists. A table that gets very narrow tightens its side spacing on its own. More on density is in layout.

episodeairedstate
S04E01, 2 years agomissingnot searched yet
S04E02, 2 years agomissingnothing found · again in 6h
S04E03, 2 years agomissingnot searched yet
S04E04, 2 years agomissingnot searched yet
S04E05, 2 years agomissingnot searched yet

behaviour

with the keyboard

  • The table is one tab stop. One row at a time is in the tab order: the row that last had focus, or the first row to begin with. The controls inside the other rows are left out, so tab crosses the table in one step instead of stopping at every checkbox and menu.
  • tab from the focused row goes into that row's own controls, its checkbox and its action menu, and then out of the table to the “show more” button or beyond. The controls in the header, the select-all checkbox and the sort buttons, come before the rows; shift + tab reaches them.
  • The up and down arrow keys move from row to row, group rows included. space selects or clears the focused row, and enter opens it, when rows open. On a group row, the left and right arrow keys close and open the group.
  • A click on a row moves focus to it, so it becomes the table's tab stop.
  • The focused row is outlined, for keyboard focus only.
  • When the row that has focus leaves the list (an action removed it, a filter hid it), or the last “show more” press removes the button, focus goes back to the table's tab stop: the row that last had focus, or the first row. It doesn't drop back to the top of the page.

with a pointer

  • A click on a row selects it or clears it, or opens the row when rows open.
  • shift + click on a checkbox, or on a row when rows don't open, selects or clears that row, and every row back to the last one changed, in the same way.
  • A click on a group row opens or closes the group.
  • Clicks on a row's own controls, such as its checkbox, buttons, links and menus, belong to those controls. They never select or open the row.
  • A click while text is selected on the page does nothing, so people can copy from a row. shift + click is the exception: it selects the range of rows, and the table stops the browser from selecting text.

The full keyboard map is on the data table's React page.

accessibility

  • A screen reader names each cell by its column and its row, because the column labels are real column headers and the row header names the row.
  • Name the table, with the heading above it or a label of its own. Nothing checks that it has one.
  • Name the rows. Each checkbox is named after its row, such as “select S04E07”. Name the row's action menu the same way, such as “actions for S04E07”.
  • Label the actions column too, with a label that is hidden on screen but read out: “actions”.
  • Say states in words. A highlight bar tells assistive technology nothing; a status cell says the state.
  • Each new “show more” count is announced. A sort is not announced, but the sorted column's header says it. The table doesn't announce changes to the selection; a selection toolbar above it does, with words like “8 selected”.

Today:

  • The arrow keys move by row only. A single cell can't take focus, so the left and right arrow keys don't move across a row's cells, and the header row is outside the arrow keys; shift + tab reaches it.
  • The table's own words are fixed, in English: “select every visible row”, the “select” in front of each row's name, and “show n more”.
  • The table doesn't announce when loading starts or ends. When it takes long, say so in words near the table.
  • ctrl + a (or cmd + a) on a group row selects the page's text; the table only takes it over on data rows.

content

  • Column labels. A noun of one or two words, lowercase: “episode”, “aired”, “state”. Put a unit in the label, “size (gb)”, rather than in every cell.
  • The row header. What people call the row, such as “S04E07” or “worker-2”, in an identifier cell. Use the same words to name the row's checkbox and its action menu, so all three agree.
  • Status. One status cell per row, taken from one table of the object's states (see status vocabulary): the state in the object's own words, and a second line for why, or what happens next.
  • Dates. A date cell, which gives the date and how long ago it was.
  • Group labels. What the group is and how many rows it holds: “The Quiet Harbour · S04 · 8 missing”. A group's name is content, shown as it is written, so spell it the way the name is spelled.
  • Group actions. A verb and the number it acts on: “grab all 8”.
  • Showing more. Keep the “100 of 2,500” form. Translate it for another language, but don't reword it.
  • Empty. What is true, in the list's own words; see empty states.

do and don't

do
episodestateactions
S04E01missing
S04E02missing
S04E03missing
The actions for each row in one action menu, named after the row. The row stays calm and has one tab stop for its actions.
don't
episodestateactions
S04E01missing
S04E02missing
S04E03missing
A row of buttons in every row: the same labels again and again, nothing reads as the next step, and the table runs out of width.
do
episodestate
S04E07missing
S04E08error: needs attention
S04E09error: needs attention
Every row says its state in words; the highlight only marks the rows that need acting on.
don't
episode
S04E07
S04E08
S04E09
A coloured bar with no words: screen readers hear nothing, and nobody can tell what the colour means.
do
episodestate

nothing missing

Every aired episode is in the library.

An empty list says what is true, in the list's own words.
don't
episodestate
A header with nothing under it: people can't tell an empty list from one that is still loading, or one that failed to load.
  • Table: the plain table, for short lists people only read.
  • Table cells: a status with its reason, a date said two ways, and an identifier.
  • Selection and bulk actions: selecting rows, and acting on them from a toolbar.
  • Worklist: the page a data table usually sits in.

specs

part spec
Frame A 1px --border on every side, --surface fill, full width. It never scrolls, so the header can stick to the page.
Header row On --bg-2. JetBrains Mono 600, 11px, letter-spacing 0.04em, --fg-muted, lowercase, one line. Padding 8px 12px, a 1px --border-2 rule below. Sticky by default (stickyHeader).
Sort button The label and a 10 × 12px glyph of two chevrons: the sorted direction drawn full, the other at 35% opacity. On hover, and on the sorted column, the label turns --fg. Keyboard focus: a 2px --focus-ring outline.
Selection column selectable. 32px wide, holding the 16px checkbox.
Group row One cell across every column on --bg-2, padding 6px 12px, at least 28px tall. Three tracks 8px apart: a 12px caret in --fg-muted (down while open, right while closed), the label, the group action. The label is mono 600 12px in --fg, as written (not lowercased), on one line with an ellipsis; on a table 480px wide or less it wraps. Its track can shrink, so a long name never widens the table. The action is a small ghost button.
Data row Cells padded 8px 12px, a 1px --border rule below, 13px in --fg-2, vertically centred. Cells take the page's font; the table cells set their own. Hover: --surface-2. Selected: --surface-selected and a 2px --cloud-blue rule on the leading edge.
Row header The first column, or the one marked rowHeader, in --fg. Pop-ins sit under its content.
Highlight rowHighlight: a 3px rule in the state's colour (--state-error, --state-warning, …) on the leading edge, in place of the blue selection rule on a selected row.
Pop-ins 4px below the row header's content, 2px apart. Label: mono 11px, --fg-dim. Value: 12px, --fg-muted, 8px after the label. A pair that doesn't fit wraps.
Empty cell One cell across every column, with no padding of its own.
Show more growing. The count in mono 12px, --fg-muted, tabular figures, and a small “show n more” button; centred, padding 12px, on --bg-2, with a 1px --border rule above.
Progress line loading: a 2px --cloud-blue bar, 30% wide, running along the top edge, 1.1s ease-in-out a run; a still, full-width 2px rule with reduced motion.
Focused row A 2px --focus-ring frame drawn inside its cells, on keyboard focus only.
setting in code what it does
Importance importance on a column: 'low', 'medium' or 'high' Low columns pop in at a table width of 720px or less, medium at 480px or less. High columns, and columns without one, always show. The row header never pops in.
Density dense Header and body cells padded 4px 8px. At 480px or less, every table's side padding drops to 8px.
Rows that open onRowPress A click outside the row's controls, or enter on the focused row, presses it.
Sticky offset --nc-dt-sticky-top How far below the top the header sticks, under another sticky bar.