ARIA Attributes Explained: When to Use Them (and When Not To)

ARIA has a reputation problem. Developers hear “accessibility” and reach for aria-label, role, and aria-hidden like seasoning, sprinkling them onto markup in the hope that more ARIA means more accessible. It doesn’t. The first rule of ARIA — literally written into the W3C spec — is: don’t use ARIA if a native HTML element already does the job. Misapplied ARIA can make a page less usable for screen reader users than no ARIA at all, because it overrides the browser’s own accessibility signals with whatever you typed, right or wrong.

For WordPress site owners, this matters because ARIA shows up constantly — in theme templates, in page builder output, in plugins that generate tabs, modals, and accordions. Understanding what ARIA actually does, and when it’s the wrong tool, helps you evaluate whether the components on your site are helping assistive technology users or quietly working against them.

What ARIA Actually Does

ARIA (Accessible Rich Internet Applications) is a set of HTML attributes that describe roles, states, and properties to assistive technology. It doesn’t change how an element looks, and it doesn’t add any behavior — no keyboard handling, no focus management, nothing functional. It only changes what gets announced through the accessibility tree that screen readers and other assistive tech read from.

That distinction trips people up constantly. Adding role="button" to a <div> tells a screen reader “this is a button,” but it does nothing to make the div focusable, clickable with Enter or Space, or reachable by keyboard. You’d have to add tabindex="0" and write JavaScript to handle key events yourself — work a real <button> element gives you for free.

The Three Categories of ARIA Attributes

  • Roles — define what an element is, like role="navigation", role="alert", or role="dialog". Roles tell assistive tech how to categorize and present the element.
  • Properties — describe characteristics that generally don’t change, like aria-label (an accessible name) or aria-describedby (a reference to descriptive text elsewhere on the page).
  • States — describe current conditions that do change, like aria-expanded on a collapsed menu or aria-checked on a custom checkbox. States need to be kept in sync with JavaScript as the UI updates.

The First Rule: Use Native HTML First

Every native HTML element — <button>, <nav>, <input>, <select>, <table> — already comes with built-in roles, states, keyboard behavior, and focus handling that browsers and assistive technology have agreed on for decades. Reaching for ARIA to recreate what a native element already provides is strictly more work and strictly more fragile.

Here’s the comparison in practice:

  • Instead of <div role="button" tabindex="0" onclick="submit()">, use <button>Submit</button> — you get keyboard support, focus styling, and form semantics without writing any of it yourself.
  • Instead of <div role="list"><div role="listitem">, use <ul><li> — the browser already exposes this correctly.
  • Instead of a styled <div> with role="checkbox" and aria-checked, use <input type="checkbox"> with CSS to restyle it — full keyboard and form behavior included.

ARIA earns its keep when you’re building something HTML has no native equivalent for — tab panels, comboboxes, tree views, live regions for dynamic status updates. Those are the cases where ARIA is doing real work, not covering for a lazier div.

Where ARIA Goes Wrong on WordPress Sites

Because ARIA is just attributes anyone can add, it’s easy for a theme or plugin developer to add it without testing whether it actually helps. A few patterns we see repeatedly when scanning WordPress sites:

aria-label overriding visible text

When an element has both visible text and an aria-label, screen readers announce the aria-label instead of the visible text — and ignore the visible text entirely. If a button says “Learn More” on screen but has aria-label="Click here", a screen reader user hears something that doesn’t match what a sighted user sees, and voice-control users who try to say “click Learn More” won’t find a match. Rule of thumb: if visible text is already accurate, don’t add an aria-label on top of it.

aria-hidden on focusable content

aria-hidden="true" removes an element from the accessibility tree — screen readers skip it entirely. That’s correct for decorative icons or duplicate content. It’s a serious bug when it’s applied to something that’s still keyboard-focusable, like a link or button inside a hidden mobile menu. The element disappears from screen reader output but a sighted keyboard user can still tab to it, landing on a control that’s invisible and unannounced.

Roles that contradict the element

We regularly see page builder output with things like role="button" on an <a href> tag, which tells assistive tech to treat a link like a button — changing the expected keyboard behavior (Enter vs. Enter/Space) and the announced element type, for no real benefit. If it navigates somewhere, it’s a link. If it triggers an action without navigating, it’s a button. Mismatched roles create confusion rather than clarity.

States that never update

Custom accordions and dropdowns often ship with aria-expanded="false" hardcoded in the markup — and it stays “false” even after the user opens the panel, because the JavaScript that toggles the visible state never touches the ARIA attribute. A screen reader user gets told the panel is collapsed no matter what’s actually on screen. If you use dynamic ARIA states, they have to move in lockstep with the actual UI state.

A Practical Way to Decide

Before adding any ARIA attribute, run through this order of operations:

  1. Can a native HTML element do this? Use it instead of ARIA.
  2. Can you change the native element’s appearance with CSS instead of building a custom widget from scratch? Restyle, don’t rebuild.
  3. If you truly need a custom widget ARIA has no native equivalent for, add the correct role, then implement all the keyboard behavior that role implies (the ARIA Authoring Practices Guide documents the expected keyboard interaction for every widget pattern).
  4. Don’t add aria-label or aria-labelledby if the visible text is already an accurate accessible name.
  5. Test any dynamic ARIA state with a real screen reader — NVDA and VoiceOver are both free — to confirm it announces what you expect, when you expect it.

This is also exactly the kind of issue that’s hard to catch by eye. A mismatched role or a stale aria-expanded value doesn’t break the visual layout — the page looks fine. It only breaks the experience for someone using a screen reader, which is why it tends to survive unnoticed through code review, QA, and client sign-off.

Take Action

LEWCA’s WCAG scanner checks your WordPress site’s actual markup for exactly these problems — conflicting roles, aria-hidden on focusable elements, and other ARIA misuse — so you’re not relying on a visual check to catch something that only shows up in the accessibility tree. It flags real code-level issues rather than papering over them with a widget, which is the same reason we’re upfront that no scanner, including ours, can promise full compliance on its own; ARIA misuse in particular often needs a human to confirm the fix matches the intended behavior. Pro adds AI-assisted code fixes, scheduled scanning, and compliance reporting if you want ongoing coverage instead of one-off checks. See pricing or download LEWCA to get started.

Font Size Control

50%100%150%180%

Page Structure

Letter Spacing

Word Spacing

Paragraph Spacing

Line Height

Text Alignment

Content Scaling

50%100%150%200%

Read Aloud

0.5x1.0x1.5x2.0x
LowNormalHigh
2070120200

How to use:

  • Tap any text to read it aloud
  • Highlight text to read it aloud
  • Adjust speed and text context with sliders
  • Adjust reading speed with slider

Color Controls

Background Colors
Text Colors

Color Blind Filters

Advanced Contrast

Page Translation

Current Language: English

Translation powered by LEWCA

Site Links