Accessibility/TreeGrid
Contents
Summary
This article is aimed to reflect implementation issues of ARIA grid and treegrid.
Examples of hierarchy
Hierarchy of ARIA grid
grid- contains cells of tabular data arranged in rows and columns, like a table row - contains cells columnheader - cell containing header information for a column in a grid columnheader columnheader row rowheader - cell containing header information for a row in a grid gridcell gridcell
Hierarchy of ARIA treegrid
ARIA treegird has similar hierarchy with ARIA grid. ARIA treegrid doesn't allow group elements to group rows of the same level like it is used for ARIA tree.
treegrid- contains cells of tabular data arranged in rows and columns, like a table row level="1" - contains cells columnheader - cell containing header information for a column in a grid columnheader columnheader row level="1" rowheader expanded="true" - cell containing header information for a row in a grid gridcell gridcell row level="2" rowheader gridcell gridcell row level="1" rowheader gridcell gridcell
ARIA elements
ARIA grid, treegrid
ARIA Attributes
- aria-multiselectable - points if more than one cell can be selected
- aria-activedescendant - points to active cell
- aria-level, aria-expanded - aren't used (general rules are applied)
Selection and Focus
Cells can be focused/selected only.
Focus is controlled by @tabindex attribute placed on cell element or by @aria-activedescedant attribute pointing to cell element if @tabindex is on grid element.
Selection is controlled by aria-selected attribute placed on row or cell accessibles. If aria-selected="true" is placed on row accessible then it means all cell accessibles are selected also, i.e. aria-selected on the cell is taken into account if there is no aria-selected="true" on its row. Therefore widget author should rely on aria-selected attribute in order to change selection. IAccessibleTable interface methods used to modify selection (like selectRow and etc) operate with aria-selected attribute as well. Widget author should watch for aria-selected attribute changes if he needs to process selection changes from JS. There is a difference between pure ARIA grids and HTML tables so that current implementation of HTML tables uses DOM selection instead of aria-selected to implement selection methods of IAccessibleTable interface. However IAccessibleTable implementation of ARIA grids based on HTML tables uses DOM selection and aria-selected attributes together.
IAccessibleTable interface
Method | Note |
---|---|
IAccessible accessibleAt(in long row, in long column) | return ARIA gridcell accessible |
IAccessible caption | return name of ARIA grid pointed by aria-describedby? |
long childIndex(in long row, in long column) | return ARIA gridcell index in table |
BSTR columnDescription(in long column) | return description of ARIA columnheader accessible pointed by aria-describedby? |
long columnExtentAt(in long row, in long column) | not supported (ARIA doesn't provide a way to expose column spans) |
columnHeader(out IAccessibleTable* table, out long* startRowIdx) | see ARIA table headers proposal |
long columnIndex(in long childIndex) | return column index by index of ARIA gridcell accessible |
long nColumns | return count of columns |
long nRows | return count of rows |
long nSelectedChildren | return count of selected gridcell accessibles (see isSelected) |
long nSelectedColumns | return count of selected columns (see isColumnSelected) |
long nSelectedRows | return count of selected rows (see isRowSelected) |
BSTR rowDescription(in long row) | return description of rowheader accessible pointed by aria-describedby? |
long rowExtentAt(in long row, in long column) | not supported (ARIA doesn't provide a way to expose row spans) |
rowHeader(out IAccessibleTable* table, out long* startRowIdx) | see ARIA table headers proposal |
long rowIndex(in long childIndex) | return row index for the index of gridcell accessible |
selectedChildren(in long maxChildren, out long** children, out long* nChildren) | return array of indexes of selected gridcell accessibles (see isSelected) |
selectedColumns(in long maxColumns, out long** columns, out long* nColumns) | return array of indexes of selected columns (see isColumnSelected) |
selectedRows(in long maxRows, out long** rows, out long* nRows) | return array of indexes of selected rows (see isRowSelected) |
IAccessible summary | return name of ARIA grid pointed by aria-labelledby? |
boolean isColumnSelected(in long column) | return true if column is selected, i.e. every gridcell of the column (or the row containing gridcell) has aria-selected="true" |
boolean isRowSelected(in long row) | return true if all gridcell of the row has aria-selected="true" or row has aria-selected="true" |
boolean isSelected(in long row, in long column) | return true if the gridcell or row containing the gridcell has aria-selected="true" |
selectRow(in long row) | set aria-selected="true" on the row (see isRowSelected also) |
selectColumn(in long column) | set aria-selected="true" on on every gridcell of the column (see isColumnSelected also) |
unselectRow(in long row) | remove aria-selected on row and on every gridcell of the row (see selectRow and isRowSelected also) |
unselectColumn(in long column) | remove aria-selected on every gridcell (and row containing the gridcell) of the column (see selectColumn and isColumnSelected also) |
boolean rowColumnExtentsAtIndex(in long index, out long* row, out long* column, out long* rowExtents, out long* columnExtents) | not supported (ARIA hasn't a way to provide row and column spans) |
IA2TableModelChange modelChange | supported, see events section |
ARIA row
ARIA Attributes
- aria-level - should be set on each row to reflect its level in the tree row hierarchy (used for treegrid only)
- aria-selected - all cells in the row are selected
- aria-activedescendant - isn't used (general rules are applied)
- aria-expanded - isn't used (general rules are applied)
Name
"JAWS should read the entire row when navigating up and down the left most column." That should mean left most column should have accessible name concatenated from accessibles name of all cells?
Object attributes
These are applicable for ARIA treegrid only.
- level
- taken from aria-level attribute, otherwise equals 1
- posinset, setsize
- taken from aria-posinset, setsize
- calculated from DOM hierarchy
- calculated based on visual arrangement (if rows are introduced by aria-owns on treegrid), see 4.21 The Owns Relationship
== ARIA gridcell==
ARIA Attributes
- aria-selected - allows single cell to be selected, does row's aria-selected is preferable under cell aria-selected, how is it going with IAccessibleTable::selectRow or selectColumn, should AT server manipulate this attributes?
- aria-expanded - are capable of expanding or collapsing the row by reflecting its expanded state. Otherwise, it is neither expandable or collapsible cells are (used for treegrid only)
- aria-level - isn't applicable (general rules are used)
Object attributes
"table-cell-index" object attribute is exposed on cells to provide an index of the cell in table (see IAccessible2::attributes). Must be used instead of IAccessible::indexInParent because rows are included into hierarchy and indexInParent returns cells index in the row.
Name
Allows name from subtree (see ARIA name computation).
Relations
described_by relations point to rowheader/columnheader accessibles
- obtained from aria-describedby
- calculated from DOM hierarchy if relations aren't pointed explicetly.
ARIA rowheader, columnheader
ARIA attributes
- aria-sort - allows to sort column?
- aria-expanded, aria-level, aria-selected - the same like it is for cell
Relations
description_for relations points to gridcell
- obtained from aria-describedby on gridcell
- calculated from DOM hierarchy if these relations aren't pointed explicetly.
David's questions
Defining tree grids
Warning: there isn't yet a common taxonomy for discussing treegrids.
What is unique about a Treegrid?
- rows can be selected (instead of just cells)
- selection can affect cell, row, col
- row can have aria-selected
- expandable/collapsible sections
- when you expand something in a treegrid, you might get something other than cells, you might get a form for example
- treegrids can have vertical, or horizontal hierarchies.
- a grid-lick section can have its own row (or col?) headers
(BPG for affordance (aria-label="select row" or aria-label="expand row below"))
Accessible Name Computation
Rows
When should rows get an accessible name?
- always?
- only when row is focusable?
- only if it has title, aria-label, aria-labelledby?
- possible heuristic: if
has no role... don't mess with it too much.
- for xul treegrids: role is tree... we have row objects which become treeitem or outline item, and the outline item will get cell children. check with orca for bustage.
- for aria: use treegrid if actual structure of the grid is being influences... if expanded content is assoc with rows use treegrid, if expanded content is assoc with cells, use grid. we need to support row and col objects.
- what about xul
- only calc row name in xul?
- xul plus aria?
- xul plus aria treegrid only (but not grid)?
States, Relations, Events
- the events and states depend on hints. if a cell has an expanded button, you need to put expanded on that button... use aria-controls.
- if cell controls row expansions use aria-controls.
- if a cell has aria-expanded then:
- if grid, assume it expands the cell
- if tree grid, assume it expands relative to a row?
Aaron was wondering this at CSUN:
- should we be more conservative with ARIA/HTML should we be putting the concatenated name on the row? do we do it for aria..
- for rows in aria should we do it fresh and new... not worry about concat names.
- if a row is focusable, then expose it (create an accessible object).