ARIA basics: the first rule, roles, states and when not to use it
ARIA is a set of HTML attributes that tells assistive technology what an element is, what state it is in and what it is called. The first rule of ARIA is to use a native HTML element when one already does the job, because ARIA changes what assistive technology is told, not how an element behaves. Add ARIA where HTML has no element or attribute for what you need, such as a tab set or an expanded state, and build the keyboard behavior yourself.
Published . Last reviewed .
ARIA (Accessible Rich Internet Applications) works on one layer only: the accessibility tree, the information a browser passes to assistive technology such as a screen reader. Adding role="button" to a div makes a screen reader announce a button. It does not make the div focusable, does not make Enter or Space work and does not style it. W3C's ARIA Authoring Practices Guide (APG) says that, unlike HTML input elements, ARIA roles do not cause browsers to provide keyboard behaviors or styling.
That is why the first rule is to use a native element: the browser then supplies the role, the name, the keyboard behavior and the states together. ARIA is still needed where HTML has no equivalent, such as tab sets, the pressed state of a toggle button and announcements of changes that a script makes (live regions).
What ARIA does and does not do
WAI-ARIA 1.2, a W3C Recommendation, describes ARIA as a supplement to the host language's semantics, not a replacement. Browsers map the roles, states and properties you set to the platform's accessibility API, and that is what a screen reader reads.
| Kind | What it carries | Examples |
|---|---|---|
| Role | The main indicator of what type of thing an element is | role="tab", role="dialog", role="status" |
| State | A characteristic that may change in response to user action or automated processes | aria-expanded, aria-pressed, aria-checked, aria-current, aria-hidden |
| Property | A characteristic essential to what the element is, or a data value tied to it | aria-label, aria-labelledby, aria-describedby, aria-controls, aria-live |
In practice, a state describes the control right now, and your script has to keep it current.
The four rules of ARIA use
W3C's Using ARIA sets out four rules. The document is now a W3C Discontinued Draft, dated 24 February 2026: it keeps the rules for historical purposes and easier reference, says there are no plans to continue the work and points readers to the APG. We use it for the rules themselves, not as a current standard.
| Rule | What it asks | An example of breaking it |
|---|---|---|
| 1. Use native HTML | If a native element or attribute already has the semantics and behavior you need, use it instead of repurposing an element and adding ARIA | A div with role="button" where a button would do |
| 2. Keep native semantics | Do not change native semantics unless you really have to | A heading given role="tab", where the page could put the heading inside a div that has the role |
| 3. Support the keyboard | Every interactive ARIA control must be usable with the keyboard | A role="button" element that cannot receive focus or ignores Enter and Space |
| 4. Do not hide focusable elements | Do not put role="presentation" or aria-hidden="true" on a focusable element | A button inside a container marked aria-hidden="true" |
The first rule has three named exceptions: the HTML feature is not implemented or lacks accessibility support, the visual design rules out a native element because it cannot be styled as required, or the feature is not in HTML at all. In our reading, check whether CSS can style the native element before you treat the second exception as true for your page.
Native HTML first: what ARIA makes you rebuild
The right-hand column is our summary of what a div rebuilt with ARIA has to supply, drawing on the linked APG pattern.
| Need | Native HTML | What the ARIA version has to add |
|---|---|---|
| A button | <button type="button"> | The role, focusability, Enter and Space handling, and a focus style (APG button pattern) |
| A checkbox | <input type="checkbox"> with a label | role="checkbox", an aria-checked value kept at true or false, a name, and Space to toggle (APG checkbox pattern) |
| Show and hide a section | <details> and <summary>, which MDN describes as a disclosure widget | A button with aria-expanded and script to show and hide the content; Enter and Space both toggle it (APG disclosure pattern) |
Using a native element does not rule ARIA out: you can add a state to one, as the example below does. Our guides to buttons versus links and accessible modals show the native elements (button, link and dialog) doing the work.
Roles: a role is a promise
The APG's first principle is that a role is a promise. Its example is <div role="button">Place Order</div>: the role promises that you have also written the script that gives the element a button's keyboard behavior. In our reading, a role without that script is false information for the person using a screen reader.
Its second principle is that ARIA can both cloak and enhance. A role overrides what an element exposes, so it can remove meaning, sometimes by accident. The APG's examples: a link given role="menuitem" is perceived as a menu item, not a link; a ul given role="navigation" leaves its list items outside any list; and a table given role="log" is no longer perceived as a table. W3C's ARIA in HTML adds that authors must not use ARIA in ways that conflict with its per-element rules, and advises against repeating a role the element already has, such as <button role="button">.
Two more points. A role="img" element needs a name, because WAI-ARIA 1.2 says authors must provide a label; our SVG accessibility guide shows where that comes up. And a landmark role is often unnecessary, in our reading, because W3C's page for 1.3.1 lists a technique that uses HTML elements to identify regions (H101) beside one that uses ARIA landmarks (ARIA11). Our landmarks and regions guide explains the choice.
States and properties: keep them true
A state that your script does not keep current is wrong information. A menu button that still says aria-expanded="false" after the menu opens tells a screen reader user nothing happened. This is a minimal disclosure: a real button, a state that flips and a panel hidden for everyone when closed.
<button type="button" id="shipping-button" aria-expanded="false" aria-controls="shipping-info">Shipping details</button>
<div id="shipping-info" hidden>
<p>Delivery times are shown at checkout.</p>
</div>
const button = document.querySelector("#shipping-button");
const panel = document.querySelector("#shipping-info");
button.addEventListener("click", () => {
const isOpen = button.getAttribute("aria-expanded") === "true";
button.setAttribute("aria-expanded", String(!isOpen));
panel.hidden = isOpen;
});
The native button brings focus, Enter and Space. Following the APG disclosure pattern, aria-expanded is true when the content is visible and false when it is hidden, and aria-controls is optional. The hidden attribute already keeps the panel out of the accessibility tree, as MDN's aria-hidden page notes. A details element would do the same job with no script.
Three more attributes need care:
aria-pressed: marks a toggle button as pressed, not pressed or mixed (WAI-ARIA 1.2). The APG button pattern says a toggle's label must not change with its state.aria-hidden: removes an element and its children from the accessibility tree. MDN notes it has no visual effect and warns against putting it on focusable elements or their ancestors. Our aria-hidden and focus guide goes deeper.aria-live: marks a region whose updates are announced. MDN's live regions guide says the most reliable approach is to put the region in the initial markup and change its text later.
Names: aria-label, aria-labelledby and aria-describedby
An accessible name is the text a screen reader announces for a control, such as "Search" for a button. Success criterion 4.1.2 Name, Role, Value requires that the name and role of every user interface component can be programmatically determined. W3C says standard HTML controls already meet it when used according to specification. Choose the source of a name in this order:
- Visible text or a native label. A button is named by its text by default (APG), and a form field by its
label. aria-labelledby. It points at other text on the page, usually visible text, and uses it as the control's name. It overridesaria-labelwhen both are present, as MDN's aria-label page explains.aria-label. Use it when there is no visible text, such as a button that holds only an icon.
aria-describedby is for a description, not a name: hint text or an error message that a field points to. MDN advises against using aria-label for instructions.
Two limits apply. WAI-ARIA 1.2 says authors must not use aria-label or aria-labelledby on roles that do not support naming from the author, and ARIA in HTML prohibits naming a plain div or span, whose default role is generic. And 2.5.3 Label in Name (Level A) asks that the accessible name contain the text presented visually, because people who use speech input say the words they see. A button that shows "Search" but is named "Find products" may not respond to "click Search". Our guides to accessible link text and accessible forms apply these rules.
ARIA mistakes to look for
| Mistake | Why it fails | Fix |
|---|---|---|
div role="button" with no keyboard support | The role adds no focus, no Enter or Space handling and no styling | Use a button element |
aria-hidden="true" on a link, button or field, or on one of their ancestors | The control stays reachable by keyboard but vanishes for screen readers | Remove the attribute, or hide the whole thing with hidden |
ul role="navigation" | The items lose their list meaning | Use a nav element around the list |
An aria-label that differs from the visible text | Speech-input users cannot say the words they see | Start the name with the visible text, or drop the aria-label |
WebAIM's 2026 Million report found that home pages with ARIA present had significantly more detected errors than pages without it, and adds that this does not necessarily mean ARIA introduced them, because those pages were also more complex.
Where ARIA belongs, and what WCAG asks
Use ARIA where HTML has no element or attribute for what you need: tab sets, the pressed or expanded state of a button, and live regions. Follow the matching pattern in the APG patterns instead of inventing roles; each lists the roles, states and keyboard behavior that go together. Our guide to accessible accordions and tabs applies the disclosure and tab patterns, and our guide to accessible menus explains why site navigation usually needs a nav element and disclosure buttons, not the ARIA menu roles. Once a widget is custom, a role is not optional: W3C lists using script to make a div or span a control without providing a role as a failure of 4.1.2 (technique F59).
WCAG does not require ARIA. It requires outcomes. Success criterion 1.3.1 asks that information, structure and relationships conveyed through presentation can be programmatically determined or are available in text, and W3C's list of sufficient techniques includes both HTML techniques, such as H101 (regions) and H42 (headings), and ARIA ones, such as ARIA11 (landmarks) and ARIA12 (role="heading"). See our 1.3.1 page, the 4.1.2 entry in our criteria reference and how to make a website accessible.
Check it yourself
- Search your code for
role=andaria-. For each, ask which native element would do the job (rule 1) and whether the role overrides what the element already is (rule 2). - Tab to every custom control and operate it. Enter and Space should work and focus should be visible (rule 3). Our keyboard accessibility test takes five minutes.
- Read the accessibility tree. Firefox's Accessibility Inspector lists each item's role and name and shows its states, and the Accessibility tab in Chrome's Elements panel shows the tree and the element's ARIA attributes (Chrome DevTools documentation).
- Listen to it. How screen readers read a page explains what to listen for.
The free accessibility bookmarklet reads the page as your browser has rendered it, including content added by JavaScript. For ARIA it flags links and buttons with no accessible name, form fields with no label and role="img" with no name. Its names follow a simplified version of the W3C accessible name algorithm, so a screen reader may announce something slightly different, and it cannot tell whether a page works with a keyboard or a screen reader.
Scan my site for free to run 16 rule-based checks on the HTML your server sends, including aria-hidden on a focusable element. The scan reads that HTML only, so ARIA that a script adds afterward is not seen. On monitored pages, the browser check adds axe-core rules for ARIA roles missing the parent or children they need, ARIA attributes with invalid values and duplicate ids used by labels or ARIA (see what we check). No automated check can say whether a role is the right one or a state is true; why scanners miss issues sets out the gap.
Keep it checked
A one-off review covers your code as it is on the day you look, and the code keeps changing. GotAlt checks the pages you monitor every week. It compares the alt text of up to six images per page with the image itself, runs its rule checks, opens monitored pages in a browser for contrast and other checks that need a rendered page (see what we check), and reports what changed. Plans are from $69 a month. Audit my whole site from $69/mo.
ARIA questions
What is ARIA in web accessibility?
ARIA stands for Accessible Rich Internet Applications. It is a set of attributes defined in the WAI-ARIA specification from W3C. They add roles, states and properties to elements so assistive technology can describe them, such as a role of tab or an expanded state. ARIA supplements HTML's own semantics and does not replace them, and it changes what assistive technology is told, not how an element behaves.
What is the first rule of ARIA?
Use a native HTML element or attribute that already has the semantics and behavior you need, instead of repurposing an element and adding ARIA. W3C's Using ARIA gives this as its first rule, and names three exceptions: missing HTML support, a design that rules out the native element, or a feature HTML lacks. That document is now a Discontinued Draft.
What is the difference between an ARIA role, a state and a property?
A role says what an element is, such as tab or dialog. A state describes a condition that changes with user action, such as aria-expanded or aria-checked, so your script must keep it current. A property is a characteristic essential to the element or a data value tied to it, such as aria-label or aria-controls. All three are ARIA attributes, and browsers pass them to assistive technology.
Is no ARIA really better than bad ARIA?
Where a native element already does the job, yes. The line is the title of a section in W3C's ARIA Authoring Practices Guide about the risk that incorrect ARIA misrepresents visual experiences for screen reader users. It is no reason to skip ARIA on a custom widget, though: W3C lists using script to make a div or span a control without a role as a failure of 4.1.2. In our reading, prefer native HTML and get any ARIA right.
Does WCAG require ARIA?
No. WCAG asks for outcomes. Success criterion 4.1.2 asks that the name and role of every user interface component can be programmatically determined, and 1.3.1 asks that information and relationships can be programmatically determined or are available in text. W3C says standard HTML controls already meet 4.1.2 when used according to specification. ARIA is one way to meet both criteria for custom components, listed among W3C's techniques alongside native HTML ones.
When should I use aria-label?
Use it when a control has no visible text to name it, such as a button that holds only an icon. When visible text exists, MDN advises pointing aria-labelledby at it instead, and a form field is already named by its label element. Keep the visible words inside the aria-label so speech-input users can say what they see, as WCAG 2.5.3 asks.
Does role="button" make a div work like a button?
No. The role changes only what assistive technology is told. W3C's ARIA Authoring Practices Guide says roles do not cause browsers to provide keyboard behaviors or styling. You would still have to make the div focusable, handle both Enter and Space and style it. A button element does all of that without script, which is why it is the first choice.
Run the automated ARIA checks first
The free scan runs 16 rule-based checks on the HTML your server sends, including aria-hidden on a focusable element and links and buttons with no accessible name. It cannot judge whether a role or state is right, so use the checks above for the rest. No signup.
Scan my site for freeRelated guides
- How to make a website accessible: the 10-step plan these guides build on.
- aria-hidden and focusable elements: a control the keyboard reaches but a screen reader cannot.
- Touch target size: the 24 by 24 pixel rule in WCAG 2.2.
- CAPTCHA accessibility: why most CAPTCHAs exclude people, and the alternatives.
- Accessible forms: labels, instructions and errors.
- Form error messages: identifying errors and suggesting fixes.
- Buttons vs links: which to use and why it matters.
- Accessible modal dialogs: focus that moves in, stays and comes back.
- Accessible navigation menus: menus and mega menus that work by keyboard.
- Accessible carousels: controls, pausing and hidden slides.
- Accordions, tabs and disclosures: the patterns and the native details element.