When to Use aria-roledescription
Permalink to "When to Use aria-roledescription"aria-roledescription replaces the words a screen reader uses to announce an element’s role. A <section> with aria-roledescription="slide" is announced as “slide” instead of “region”; a grid with aria-roledescription="spreadsheet" is announced as “spreadsheet” instead of “grid”. It changes only the spoken word — the role, and everything users know about how to operate that role, stays the same.
That last point is why it is dangerous in data interfaces. Screen reader users rely on role names to know what keys will work: “grid” means arrow keys move between cells; “button” means Enter and Space activate. Replace those words with invented ones and users lose the cue. This page sets out the narrow cases where it helps and the common ones where it harms. It belongs to accessible names & descriptions for data widgets.
Spec reference
Permalink to "Spec reference"ARIA 1.2 defines aria-roledescription as “a human-readable, author-localized description for the role of an element.” Its rules:
- The element must have a valid explicit or implicit role;
aria-roledescriptionon a generic<div>or<span>is ignored by browsers. - The value must not be empty or whitespace only.
- Authors should limit it to cases where the role is clarified for users, and should not use it to change the meaning of standard widgets.
- Some screen readers ignore it in some contexts; others announce it in place of the role everywhere, including in element lists.
Criteria: SC 4.1.2 Name, Role, Value — the role exposed must reflect the element’s behaviour. Changing the spoken role to something that implies different behaviour works against this criterion’s intent.
When to use it — and when not to
Permalink to "When to use it — and when not to"Reasonable uses are container-like elements whose generic role word adds nothing and whose domain word helps: role="group" slides in a carousel (“slide 3 of 8”), a region presented as a “dashboard card” when users navigate by regions. The element’s behaviour is not affected by the word.
Harmful uses in data interfaces:
- A grid described as “spreadsheet”, “data table” or “report”. Users hear a word that does not tell them arrow keys will work, or tells them table reading commands will work when they will not.
- A button described as “toggle” or “action”. “Button” already tells users how to activate it; “toggle” suggests
aria-pressed, which may not be there. - A
rowdescribed as “record” or agridcellas “field”. Every cell announcement gets a non-standard word, and some readers then drop row and column position.
The misapplication to name is using aria-roledescription to fix a wrong role. If a component is announced as “grid” but behaves like a table, the fix is to change the role, as in choosing between grid and table roles, not to rename it.
Annotated code example
Permalink to "Annotated code example"<!-- Reasonable: a carousel of chart slides. Role word "group" adds nothing -->
<section aria-roledescription="carousel" aria-label="Quarterly charts">
<div role="group" aria-roledescription="slide" aria-label="2 of 4: Revenue by region">
<!-- chart and its text alternative -->
</div>
</section>
<!-- Harmful: renaming a grid hides its keyboard model -->
<div role="grid" aria-roledescription="spreadsheet" aria-label="Budget">…</div>
<!-- Better: keep the role word, put the domain word in the name -->
<div role="grid" aria-label="Budget spreadsheet">…</div>
<!-- Harmful: renaming a button -->
<button aria-roledescription="toggle">Star</button>
<!-- Better: expose the actual state -->
<button aria-pressed="false">Star</button>
The pattern in both corrections is the same: put domain vocabulary in the name, where it describes the thing, and leave the role word alone, where it describes how to use the thing. “Budget spreadsheet, grid” tells users both what it is and how to operate it.
Keyboard & AT behaviour
Permalink to "Keyboard & AT behaviour"| Markup | NVDA | JAWS | VoiceOver |
|---|---|---|---|
role="group" + aria-roledescription="slide" |
“slide, 2 of 4: Revenue by region” | Same | Same |
role="grid" + aria-roledescription="spreadsheet" |
“Budget, spreadsheet” (no “grid”) | “Budget, spreadsheet” | “Budget, spreadsheet” |
aria-label="Budget spreadsheet" on the grid |
“Budget spreadsheet, grid” | Same | Same |
aria-roledescription on a <div> with no role |
Ignored | Ignored | Ignored |
Empty aria-roledescription="" |
Invalid; ignored or role dropped | Varies | Varies |
Integration context
Permalink to "Integration context"Most teams reach for aria-roledescription when a dashboard card, KPI tile or chart container “should be called something”. A labelled region or group with a good name almost always does the job better — see accessible KPI cards and sparklines and landmarks and headings for dashboards.
Names for grids themselves come from visible headings via aria-labelledby.
Gotchas
Permalink to "Gotchas"Localisation. The value is spoken verbatim, so it must be translated. Hard-coded English role descriptions on a localised page are read in English.
Element lists. Some readers list elements by their role description, so a “spreadsheet” does not appear in the list of grids or tables where users look for it.
Braille. Role descriptions replace the short braille role abbreviation with the full word, which takes more cells on a braille display.
Design system notes
Permalink to "Design system notes"Do not expose aria-roledescription as a general prop on data components. A grid, table, button or icon-button component that accepts arbitrary ARIA attributes will eventually be given a role description by someone trying to make it “sound right”. If a carousel or slide component needs one, set it inside that component with a localised string, and keep the prop off the public API of everything users operate. Linting can help: an ESLint rule that flags aria-roledescription outside an allow-list of components catches the rest in review.
Testing checklist
Permalink to "Testing checklist"FAQ
Permalink to "FAQ"What does aria-roledescription do?
It replaces the word a screen reader uses for an element’s role — “slide” instead of “group”, for example. It does not change the role itself or its keyboard behaviour; it only changes what is spoken.
Should I use aria-roledescription on a data grid?
No. The word “grid” tells screen reader users that arrow keys move between cells. Replacing it with “spreadsheet” or “report” removes that cue. Put the domain word in the grid’s name instead.
Is aria-roledescription allowed on a div?
Only if the div has a valid role. On a generic element with no role it is ignored, because there is no role to redescribe.
Does aria-roledescription affect braille displays?
Yes. Braille displays normally show a short standard abbreviation for each role; a role description replaces it with the full custom word, which uses more of a small display and is unfamiliar to braille readers who scan by abbreviation.
When is aria-roledescription appropriate?
For container roles where the generic word adds nothing and a domain word helps orientation, such as slides in a carousel. Keep it off anything users operate directly.
Related
Permalink to "Related"- Choosing between grid and table roles — picking the real role first
- Labelling grids with aria-labelledby — naming instead of redescribing
- Accessible KPI cards — where teams are tempted to use it