Skip to content

Accessibility

@toolbox-web/grid follows the WAI-ARIA Grid Pattern to provide an accessible data grid experience. This page documents the ARIA attributes, keyboard interactions, and best practices.

The grid applies the following ARIA roles and attributes automatically:

ElementRoleAttributes
<tbw-grid>gridaria-rowcount, aria-colcount, aria-multiselectable
Header containerrowgroup
Header rowrowaria-rowindex="1"
Header cellcolumnheaderaria-sort, aria-colindex
Body containerrowgroup
Data rowrowaria-rowindex, aria-selected, aria-expanded
Data cellgridcellaria-colindex, aria-selected, aria-readonly
AttributeApplied WhenValues
aria-sortColumn is sortedascending, descending, none
aria-selectedRow or cell is selectedtrue, false
aria-expandedRow grouping/tree is activetrue, false
aria-multiselectableSelection plugin allows multi-selecttrue
aria-readonlyCell is not editabletrue
aria-rowindexAlways (1-based)Row position in full dataset
aria-colindexAlways (1-based)Column position

The grid implements full keyboard navigation following the WAI-ARIA grid pattern:

KeyAction
/ Move focus between rows
/ Move focus between cells
HomeMove to first cell in row
EndMove to last cell in row
Ctrl + HomeMove to first cell in grid
Ctrl + EndMove to last cell in grid
PgUpScroll up one viewport
PgDnScroll down one viewport
⇥ TabMove to next cell (wraps to next row)
⇧ Shift + ⇥ TabMove to previous cell (wraps to previous row)
KeyAction
SpaceToggle row selection
⇧ Shift + Extend range selection
Ctrl + ASelect all rows/cells
EscClear selection
KeyAction
↵ EnterStart editing focused cell
F2Start editing (alternative)
EscCancel editing
⇥ TabCommit and move to next cell
⇧ Shift + ⇥ TabCommit and move to previous cell
↵ Enter (while editing)Commit value
KeyAction
SpaceToggle expand/collapse on group or tree node
KeyAction
⇧ Shift + F10 / ☰ MenuOpen context menu at focused cell
/ Navigate menu items
↵ Enter / SpaceActivate menu item
EscClose menu

The grid uses visible focus indicators that meet WCAG 2.1 Level AA requirements:

tbw-grid {
/* Customize focus ring */
--tbw-color-focus-ring: #2563eb;
}

The focus ring is 2px solid and uses outline (not border) so it doesn’t affect layout.

When editing a cell, focus is trapped within the editor until the user commits (Enter/Tab) or cancels (Escape). Overlay editors (date pickers, dropdowns) use registerExternalFocusContainer() to extend the focus trap.

The grid uses a roving tabindex pattern:

  • Only the currently focused cell has tabindex="0"
  • All other cells have tabindex="-1"
  • This means Tab moves focus out of the grid, and Shift+Tab moves focus back to the last focused cell

Provide accessible labels for screen readers:

<tbw-grid aria-label="Employee directory">

Or reference a visible heading:

<h2 id="grid-heading">Employees</h2>
<tbw-grid aria-labelledby="grid-heading">

The grid uses aria-live regions to announce dynamic changes to screen readers:

  • Sort changes (“Sorted by Name, ascending”)
  • Filter changes (“Filter applied on Name”, “All filters cleared”)

Column headers include:

  • Column name via text content
  • Sort direction via aria-sort
  • Filter state via aria-description (“Filtered”)

The grid’s CSS variable system makes high contrast easy:

/* High contrast theme */
tbw-grid.high-contrast {
--tbw-color-bg: #000;
--tbw-color-fg: #fff;
--tbw-color-border: #fff;
--tbw-color-header-bg: #1a1a1a;
--tbw-color-row-hover: #333;
--tbw-color-focus-ring: #ffff00;
--tbw-color-accent: #00ffff;
}
import '@toolbox-web/grid/themes/dg-theme-contrast.css';

The grid ships with a built-in @media (forced-colors: active) block that remaps all theming variables to Windows system colors (CanvasText, Canvas, Highlight, HighlightText). Focus rings and selected rows are also overridden to use Highlight. No extra configuration needed — it works automatically.

CriterionLevelStatusNotes
1.1.1 Non-text ContentAIcons have text alternatives
1.3.1 Info and RelationshipsAARIA roles convey structure
1.3.2 Meaningful SequenceADOM order matches visual order
1.4.1 Use of ColorAStatus not conveyed by color alone
1.4.3 Contrast (Min)AADefault theme meets 4.5:1 ratio
1.4.11 Non-text ContrastAAFocus indicators visible at 3:1
2.1.1 KeyboardAAll functions accessible via keyboard
2.1.2 No Keyboard TrapATab exits the grid; Escape exits editors
2.4.3 Focus OrderALogical focus order follows grid structure
2.4.7 Focus VisibleAAClear focus indicators
4.1.2 Name, Role, ValueAARIA attributes on all interactive elements

The grid handles most accessibility concerns out of the box:

  • ARIA roles & attributesrole="grid", role="row", role="gridcell", aria-rowcount, aria-colcount, aria-rowindex, aria-colindex are always set
  • Keyboard navigation — Arrow keys, Tab, Enter, Home/End, PgUp/PgDn all work by default (core feature, not a plugin)
  • Column headers — Always rendered with role="columnheader"; cannot be hidden
  • Column type inference — Types (number, date, boolean) are auto-detected from the first data row
  • Grid label — Auto-derived from the shell title (<tbw-grid-header title="..."> or shell.header.title config)
  • Windows High Contrastforced-colors media query is built into core CSS
  • Live announcements — Sort and filter changes are announced via aria-live regions
  • Plugin ARIA — Selection, editing, filtering, tree, and grouping plugins manage their own ARIA attributes (aria-selected, aria-readonly, aria-expanded, aria-multiselectable, aria-description)

These require explicit action:

  1. Provide a grid label when not using a shell — Without <tbw-grid-header title="...">, set gridAriaLabel in config or add aria-label on the element
  2. Test with screen readers — NVDA (Windows), VoiceOver (macOS), Orca (Linux)
  3. Don’t override keyboard handling — The grid follows WAI-ARIA patterns; custom key listeners may conflict
  4. Use the contrast theme for additional a11y — Import dg-theme-contrast.css for higher contrast beyond the built-in forced-colors support
AI assistants: For complete API documentation, implementation guides, and code examples for this library, see https://raw.githubusercontent.com/OysteinAmundsen/toolbox/main/llms-full.txt