Home/Appearance & Platform/Accessibility
Appearance & Platform

Accessibility

A grid that's WCAG 2.1 AA out of the box: full ARIA, a live region that speaks sort/filter/load/edit, and complete keyboard reach including header sorting — all on by default, nothing to configure, and gated by axe-core in CI.

Name
Team
City
Salary
Amira Hassan
Engineering
Cairo
$42,000
Omar Nabil
Design
Remote
$43,700
Lena Rashid
Sales
London
$45,400
Yusuf Zaki
Support
Tokyo
$47,100
Nadia Farouk
Finance
Austin
$48,800
Karim Salem
Engineering
Berlin
$50,500
Sara Fahmy
Design
Cairo
$52,200
Hana Khaled
Sales
Remote
$53,900
Tarek Aziz
Support
London
$55,600
Maya Mansour
Finance
Tokyo
$57,300
Amira Hassan
Engineering
Austin
$59,000
Omar Nabil
Design
Berlin
$60,700
Lena Rashid
Sales
Cairo
$62,400
Yusuf Zaki
Support
Remote
$64,100
Nadia Farouk
Finance
London
$65,800
Karim Salem
Engineering
Tokyo
$67,500
Sara Fahmy
Design
Austin
$69,200
Hana Khaled
Sales
Berlin
$70,900
Tarek Aziz
Support
Cairo
$72,600
Maya Mansour
Finance
Remote
$74,300
Rows per page:
1–20 of 120

Accessible by default — nothing to switch on

The grid ships as a correct WCAG 2.1 AA component out of the box: full ARIA structure, a live region that speaks state changes, and complete keyboard reach. There is no accessibility: true flag and no per-column wiring — turn on sorting, selection, filtering, paging and editing (all shown above, all free) and the accessible behaviour comes with them.

Screen readers hear what happens

A single polite live region per grid announces the events that matter, in your app's language (every string is a GridMessages key, English and Arabic built in). Turn on a screen reader and try the grid above:

When you……the grid announces
Sort a column"Name: sorted ascending" / "descending" / "Sort cleared"
Type in a filterthe result count — "8 results"
Load or page the data"120 rows loaded" · "Page 2 of 6"
Commit an edit"Salary updated"
Select all / clear"20 rows selected" · "Selection cleared"

Announcements fire on state events only — scrolling thousands of virtual rows never makes a sound, and a burst of rapid changes collapses into one message. The real row count comes from your data source, so it's truthful even when only a page is loaded.

Naming the grid

A screen reader announces the grid by name the moment focus enters it. By default that name is Data Grid, which is enough on a page with one grid and useless on a page with two — a listener hears the same three words twice and has no way to tell which one they landed in.

Give it a real name with config.messages.gridLabel. The grid on this page is called Employee directory; that string becomes the grid's accessible name, and it is the first thing a screen-reader user hears here.

config: GridConfig = {
  messages: { gridLabel: 'Employee directory' }
};

messages holds every other string the grid speaks or shows too — the empty and error text, the pager labels, the names on the selection checkboxes. Setting one leaves the rest at their defaults.

Everything works from the keyboard

Focus enters on the first cell; arrows move it and the grid scrolls to follow. The header row is part of the path — arrow up from the top row onto a column header and press Enter or Space to sort it. Arrow onto the filter row and Enter steps into the input, Escape steps back out.

KeysWhat they do
↑ ↓ ← →Move one cell — across the body, the filter row, and the header row.
Tab / Shift+TabNext / previous cell. At the last cell focus leaves the grid — never a trap.
Home / End · Ctrl+Home / Ctrl+EndRow edges · grid corners.
Enter / Space on a headerSort the column.
Enter on a cellEdit it — or, when the cell holds a link or button, step into that content (Escape returns).
Space on a rowSelect / deselect it.

Proven, not promised

The grid's accessibility is enforced by an automated axe-core gate in CI: the demo grids are scanned against WCAG 2.1 AA on every change and must stay at zero violations. Correct row/column counts and indices, aria-sort, group and tree semantics, labelled controls, and a clean role subtree are all verified — not left to a manual audit.

Many grids make accessibility your job — you hand-tune DOM order (which then breaks arrow navigation), force off column virtualisation to satisfy a reader, and write per-column keyboard handlers to reach a link inside a cell. Here there is nothing to configure: the structure, the announcements and the keyboard model are the default, and the row count is always the real one.

Accessibility API

PropertyTypeDefaultDescription
config.messages.gridLabelstring'Data Grid'The grid's accessible name — the first thing a screen reader announces on entry. Name it whenever a page holds more than one grid.
config.messagesPartial<GridMessages>en / ar built inAll ARIA labels and screen-reader announcements. Override any key to translate or reword; set a key to '' to silence that announcement.
aria-live announcementsautomaticpoliteSort, filter/result count, load, page, edit commit and select-all speak through one polite region. Live-update streams stay silent by design.
role / aria-rowcount / aria-colcountautomatic—grid (or treegrid with grouping/tree) on a clean role subtree; true counts and indices in display space, correct across pinned regions and virtual scroll.
config.keyboardNavbooleantrueThe keyboard model incl. header-row sorting and the interactive-cell pattern. Set false to opt out.
--gc-cell-focus-outline / -width / -offsetCSS varstheme accent, 2px, -2pxThe keyboard focus ring (shared by body, header and filter cells). :focus-visible only — a mouse click never paints it.