A grid follows the WAI-ARIA grid pattern.
The name of a grid
Give each grid a name: label="Orders", or label_id with the id of a
heading that names it. A screen reader says the name when the grid gets
the focus.
The roles
- The scroll box has the
gridrole,aria-rowcount(every row of the query, and the header) andaria-colcount, andaria-multiselectable. - The header is a
rowofcolumnheadercells; a column that sorts hasaria-sort(ascendingordescendingon the first column of the order,noneon the others). - Each row has
aria-rowindex, its place among all the rows, and each cellaria-colindex, so that a screen reader says "row 50,006 of 100,001" for a row in the middle of a large grid, though only the rows on the screen are in the page. - A selected cell has
aria-selected="true". - A row that is coming from the server has
aria-busy="true". - A tree's scroll box has the
treegridrole, and each rowaria-level,aria-setsizeandaria-posinset, andaria-expandedwhen it has children (see Trees and details). - An open detail is a
regionnamed "Details"; Alt+↓ goes into it and Escape comes back to its row.
The focus
The grid is one stop of the Tab key. The focus stays on the grid, and the
active cell is its aria-activedescendant: a screen reader follows the
cell as the arrows move it, while the rows come and go. See
Keyboard and copy for the keys.
The filter menu
The funnel of a header is a button named "Filter" and the column's label,
with aria-haspopup="dialog" and aria-expanded. The menu is a dialog
with the same name; the focus goes to its first field, and comes back to
the header when it closes. An enum's values are a group of checkboxes.
Each chip has a button that takes its filter away, named for it.
A column with items of the app's own and no filter has a button named for the column's menu instead, with three dots.
The menu of a cell
In a grid with one (see Menus of your own), the menu of a
cell is a menu named for its column, of menuitems, with a
separator between its groups. It opens on the context-menu key or
Shift+F10, as on a right click; the focus goes to its first item. ↑ and
↓ move, Home and End go to the ends, a letter to the next item that
starts with it, Enter or Space runs an item, and Escape or Tab closes
it; the focus comes back to the grid, on the same cell. The panel of an
item is a dialog named by the item, with the focus in it, and Escape
closes it.
Editing
The editor of a cell is an input named by its column's label, with the
focus while it is open; the focus comes back to the grid when it closes.
A cell the server refused has aria-invalid="true" and the error as its
title, and the live region says the error. In a column that edits, a cell
has aria-readonly: "true" when the row's state makes it read-only.
Other people
The avatars are a group named by messages["people"] ("Also here"),
each with the person's name as its title and label. The lines and labels
of other people's cells are hidden from screen readers (they move as the
others move); a cell that another person edits says so when the person
tries to edit it.
Announcements
A live region says how many rows a sort, a filter or a search gives
("9,412 rows"), how many rows were selected or copied, and why a query
was refused. Its words are in messages.
Motion
Under prefers-reduced-motion, the grid has no transitions.