ARIA — Accessible Rich Internet Applications — was created to make the things HTML can’t describe accessible to screen readers: custom dropdowns, tab panels, live-updating content. It’s powerful and necessary. It’s also, by a wide margin, the most misused tool in front-end accessibility. The official guidance even has a name for the failure mode: “No ARIA is better than Bad ARIA” (W3C ARIA Authoring Practices Guide).
That isn’t a slogan. It’s a measured pattern. In WebAIM’s 2026 analysis of the top one million home pages, 82.7% used ARIA — and pages with ARIA present averaged 59.1 detected errors, versus 42 on pages without it (WebAIM Million 2026). More ARIA correlated with more barriers, year after year.
The first rule of ARIA is: don’t use ARIA
The W3C states it plainly. The first rule of ARIA use is that if you can use a native HTML element with the semantics and behavior you require already built in, do that instead of repurposing a generic element and bolting on an ARIA role (W3C, Using ARIA).
The reason is mechanical, not stylistic. A native <button> is focusable, fires on click and on Enter and on Space, exposes a “button” role to assistive tech, and works in every browser without a line of JavaScript. The popular alternative — <div role="button"> — does exactly one of those things. As MDN documents, role="button" tells assistive tech the element is a button but adds no click handling, no keyboard focus, and no Space/Enter activation. You have to rebuild all of it by hand, and most teams forget at least one piece. The result is a control a mouse user can click but a keyboard user can’t reach — a keyboard trap or dead end that a real button would never have created.
How ARIA actually backfires
Bad ARIA doesn’t sit there harmlessly. It overrides what the browser already knew and feeds assistive tech something worse. The recurring culprits:
- Roles that lie.
<div role="button">with no keyboard handling, orrole="navigation"slapped on something that isn’t a nav. The W3C’s own framing: using a role without fulfilling its promise is like a “Place Order” button that empties the cart (APG Read Me First). aria-hidden="true"on the wrong thing. Meant to hide decoration, it routinely hides real content — or, worse, hides a focusable element, so a keyboard user can tab to a control a screen reader insists doesn’t exist.- Redundant labels that erase context. An
aria-labelon a link or input replaces the visible text the user can see. Mismatched or vague labels strip away meaning that was already correct. - Broken references.
aria-labelledbyandaria-describedbypointing at IDs that don’t exist on the page — so the label simply vanishes for screen-reader users.
None of these show up for a sighted mouse user, which is exactly why they survive into production. They only surface when someone actually navigates with a screen reader or keyboard — the precise audience ARIA was supposed to serve.
Where ARIA is genuinely the right answer
ARIA earns its place wherever HTML has no native equivalent. You can’t build these out of plain elements, and the WCAG success criteria expect them to be conveyed:
- Custom interactive widgets — tabs, comboboxes, tree views, menus, sliders, and modal dialogs. The W3C ARIA Authoring Practices Guide publishes vetted, keyboard-complete patterns for each. Follow them; don’t improvise.
- Live regions —
aria-livefor content that updates without a page reload, like form-validation messages, cart totals, or a “search results updated” notice. - Naming and relationships —
aria-label/aria-labelledbywhen there’s genuinely no visible text to associate (an icon-only button, for example), andaria-expanded/aria-currentto expose state HTML can’t.
The dividing line is simple. Is there a native element that already does this? Use it. Is there genuinely not one? Reach for ARIA — and follow the APG pattern exactly, including the keyboard behavior, because ARIA roles never add keyboard support on their own.
A quick self-audit
Before you ship a component, ask three questions:
- Could a native element do this? If a
<button>,<a>,<nav>,<label>,<select>, or<details>covers it, delete the ARIA and use the element. - Did I rebuild the keyboard behavior? Any custom widget with a role needs focus management and key handling to match. No exceptions.
- Does it announce correctly? Turn on VoiceOver, NVDA, or TalkBack and listen. This is non-negotiable, and it’s why automated scanners miss most ARIA problems — a tool can’t hear that a label is wrong, only that one exists.
This is also why we’re openly against accessibility overlays. Overlays inject ARIA in bulk, by script, with no understanding of your markup — manufacturing exactly the “bad ARIA” the data warns about. Curbcut does the opposite: manual remediation, where a human reads the component, removes the ARIA that’s hurting, and adds only what the WCAG 2.1 AA standard genuinely requires. For small businesses, that’s the difference between code that passes a scan and code that actually works for a disabled customer at checkout.
Where this leaves you
ARIA isn’t the enemy — unexamined ARIA is. The strongest accessibility move most sites can make isn’t adding attributes; it’s deleting the ones that override perfectly good HTML, then rebuilding the handful of custom widgets correctly. If you’re not sure which is which on your own site, an accessibility audit will tell you, and proper remediation will fix it for good.
This article is educational, not legal advice. For questions about your specific ADA or WCAG obligations, consult a qualified accessibility professional or attorney.
Want a fast read on your current markup? Start with a free accessibility scan.