ARIA · WCAG · Guide

WCAG, ARIA, ROLE: The 2026 Guide to When NOT to Use ARIA

An oxblood and cream editorial illustration of a checklist with some lines crossed out in brick red ink and others checked in the same tone, evoking a code audit.
  • ARIA
  • WCAG
  • Guide

A team we worked with got back an accessibility audit with a page of findings. Missing labels, a few contrast issues, some keyboard traps. Normal stuff. So they did what a lot of teams do: they had an engineer spend a sprint sprinkling role and aria-* attributes across the app, on the theory that more ARIA equals more accessible.

The follow up audit came back worse.

Not because the original issues were still there. They were mostly fixed. The new problems were the ARIA attributes themselves. Several of them were actively lying to screen readers and other assistive technology about what was actually on the page, turning readable buttons into confusing black boxes and hiding real content from the very users the audit was supposed to help.

The Stat: The first rule of ARIA use, published in the W3C's own ARIA Authoring Practices Guide, is: if a native HTML element already has the semantics you need, use it instead of repurposing an element and adding a role. (Source: W3C WAI ARIA Authoring Practices Guide)

Here is that rule made visible, with the four patterns that break it most often in real codebases.

Four common ARIA misuse patterns and their fixes A four row diagram on a cream background. Each row shows a WRONG code snippet marked with an oxblood X and a RIGHT code snippet marked with an oxblood checkmark. The four rows cover div with role button, role presentation on meaningful content, a redundant role on a native element, and aria-hidden left on a focusable element. WRONG RIGHT <div role="button">Save</div> <button>Save</button> role="presentation" on a live price and stock count no role, plain markup, content stays readable <nav role="navigation"> <nav> <a href aria-hidden="true"> aria-hidden removed

The catalog: four ways teams break the first rule

We already wrote about why the first rule of ARIA exists and why it gets ignored anyway. This piece is the companion to that one. Instead of the philosophy, here is the field guide: the exact patterns that show up in real pull requests, why each one is worse than doing nothing, and the one line fix.

1. The div with role="button" that forgot how to be a button

This is the classic. Someone needs a clickable element that does not look like a default browser button, so they reach for a div, add role="button", wire up an onClick handler, and ship it.

To a sighted mouse user, it works fine. To a screen reader user, it announces as a button. But it is not a button. It has no built in keyboard support, so pressing Tab may never land on it, and pressing Enter or Space does nothing unless a developer manually re-implements keyboard handling that a real <button> gives you for free. The role attribute made a promise that the rest of the markup never kept.

The fix is almost always to just use <button>. You can restyle a button element into anything you want with CSS. What you cannot do with CSS is give a div a keyboard.

2. role="presentation" hiding real, meaningful content

role="presentation" (and its cousin role="none") tells assistive technology "ignore this element's semantics, it's purely decorative." That is genuinely useful for a wrapper div that exists only for layout.

It is genuinely harmful when it lands on something that carries actual information: a price, a stock count, a status badge, a table used to present real tabular data rather than for layout. We have seen this happen when a component library's default styling gets stripped down for a redesign, and whoever did the cleanup left the role="presentation" that used to suppress a decorative icon, except it now sits on the element holding the number a customer needs to see. Screen reader users skip right past it. The content is on the screen and invisible to assistive technology at the same time, which is a strange and specific kind of broken.

The fix is to ask, every time you see role="presentation" in a diff: does this element contain anything a user needs to know? If yes, the role comes off.

3. Redundant roles on native elements that already have one

<nav role="navigation">. <button role="button">. <input type="checkbox" role="checkbox">. Each of these roles is already implicit in the element itself. Adding it back explicitly does not add clarity, it adds a second source of truth that can drift out of sync with the element over time, and it adds nothing for the user, because the browser was already exposing the correct role.

This one is rarely dangerous on its own. It is a smell. It usually means whoever wrote the line did not know the role was automatic, which is exactly the mindset that produces the more serious mistakes on this list. The fix is simply to delete it.

4. aria-hidden left on a focusable element

This is the one that causes the strangest bug reports. A modal closes, a menu collapses, a tooltip dismisses, and the developer sets aria-hidden="true" on the container to hide it from assistive technology while it animates out or stays in the DOM unused. Reasonable so far.

The trap: if that container still holds a link, button, or input that keeps its default tabindex, a keyboard or screen reader user can still Tab into it. Now they are focused on an element the accessibility tree says does not exist. Some screen readers announce nothing. Some behave unpredictably. Either way, the user is stuck inside a hole in the page.

The fix is to remove aria-hidden when the content becomes interactive again, or to set tabindex="-1" (or use the inert attribute) on everything inside the hidden container so focus cannot land there in the first place. We covered a close cousin of this problem, icon only controls that look interactive but skip real semantics entirely, in our hamburger menu confession piece, which is worth reading alongside this one.

A two minute checklist before you ship

None of these four patterns require a rewrite to fix. They require a second pass over the diff, asking a short list of questions before the pull request merges.

  • Is there a native element that already does this? A button, a, select, input, nav, table, or dialog element comes with keyboard support, focus handling, and a role built in. Reach for it before reaching for a div plus a role.
  • Does this role match what the element actually does? If you write role="button" on anything, that element now has to support Tab, Enter, and Space exactly like a real button does. If it does not yet, the role is a promise you have not kept.
  • Does role="presentation" or role="none" sit on anything a user needs to read? If the element carries a price, a count, a status, or any other piece of real information, the role should come off.
  • When something gets hidden, does focus get hidden with it? Any time aria-hidden="true" lands on a container, check whether links, buttons, or inputs inside it can still be tabbed to. If they can, either remove the attribute when the content is interactive again or block focus with tabindex="-1" or inert.
  • Is the role just restating what the element already announces? A redundant role like role="navigation" on a nav element is not urgent, but it is a sign the same author may be adding roles out of habit rather than need. Worth a quick look at their other changes.

Run through those five questions on any component that touches ARIA, and most of the damage in this catalog never ships in the first place.

The rule that ties all four together

Every one of these four patterns comes from the same root cause: treating ARIA as decoration you add for credit, instead of a contract you have to keep. Per the W3C's own ARIA Authoring Practices Guide read me first, ARIA only changes what assistive technology is told about an element. It changes nothing about keyboard behavior, focus order, or what actually renders. If you add a role, you have promised the behavior that role implies, and now you have to build it. If you do not need to make that promise, the W3C's guidance on using ARIA is blunt about it: no ARIA is better than bad ARIA.

Before your next audit turns up the same surprise ours did, it is worth running your own components against this catalog. Our free tools can help you spot exactly where a role, an aria-hidden, or a stray role="presentation" is quietly working against you instead of for you.

If you want a second set of eyes on a specific component or a full audit before it becomes a support ticket, reach out to a real person on our team at experts@wcag.world, or start with our free tools to see what's already hiding in your markup.