Also available in: Español · Português · Français · العربية
ARIA roles: which element needs one, and which already has it
Look up any HTML element and any ARIA role and find out whether you should write it, whether you may, or whether the element is already that thing.
What is an ARIA role?
An ARIA role tells assistive technology what a piece of markup is: a button, a navigation landmark, a heading, a dialog. You write it as role="button" and it changes how a screen reader announces the element and what a user can do with it.
WAI-ARIA defines the roles themselves. A second specification, ARIA in HTML, answers the question people actually arrive with — which roles may go on which HTML element — and it does so in a table covering 139 elements. That table is what this page is built from, and it is the one worth reading, because roles are not interchangeable across elements.
The single most useful thing in it is easy to miss. 81 of those 139 elements already carry a role without any attribute at all, and the table's own header says assigning those in markup is NOT RECOMMENDED. A button element is already a button. An h1 is already a heading with a level. Most of the time the correct answer to "which role goes here" is none.
How to use it
- Type the element. Just the tag name — angle brackets and capitals are fine. Where the specification qualifies an element, a bare name resolves to the qualified row: typing a gets the rule for a with href.
- Type the role you were about to write. You get one of four answers: the element already has it, it is allowed, it is not allowed here, or the rule is conditional and no straight answer exists.
- Then look at the reverse index underneath. It lists the elements that already have that role with no attribute, separately from those that will merely accept it. That is usually the better way to solve the problem.
Redundant is not the same as wrong
Writing role="button" on a button element is valid markup. It is not an error and nothing will break. The specification marks it NOT RECOMMENDED because it adds nothing and because it can drift: change the element later and the role stays behind, now describing something that no longer exists. This page reports that case as its own verdict rather than folding it in with the genuine errors, since telling someone their working markup is broken is worse than saying nothing.
The genuinely disallowed cases are a different matter. 51 elements accept no role beyond the one they already have — main, body, html, base, caption and the rest — so role="navigation" on a main element is simply not permitted. 37 more accept only an enumerated set: an a with href will take button, checkbox, menuitem, menuitemcheckbox, menuitemradio, option, radio, switch, tab or tree, and nothing else. And 41 elements, the blank slates like span and abbr, accept any role at all.
That leaves the roles themselves, 75 of which the table names. If you need one, the reverse index is the shortcut: ask which elements already are a button before you decide to make one out of a div.
Ten elements where this page will not answer
Ten of the 139 rules are written with a condition, and the tool refuses to give a verdict on them rather than guessing. td, th and tr depend on the role of the ancestor table element. div depends on whether it is a direct child of dl. figure depends on whether it has a figcaption descendant. label depends on whether it is associated with a labelable element.
In every one of those cases the specification declines to state an unconditional rule, so a tool that produced a confident yes or no would be inventing one. The specification's own sentence is shown instead, to be read against your actual markup. That is the honest answer, and it is why this page shows the source text for every element rather than only its own summary.
Two further limits worth stating. This is the element table only — ARIA in HTML has two more tables, one about HTML features and one about which descendants a role allows, and neither is covered here. And the page tells you what is permitted, not what is a good idea: a permitted role can still be the wrong one, and no table can tell you whether your widget actually behaves like a tab.
Why is it free?
The table travels with the page as a few kilobytes and every lookup runs in your own browser. Nothing you type is uploaded, nothing is logged, and there is no account to create.
No sign-up, no limits, and no watermark on anything you copy.