← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

ARIA Roles & Attributes

frontend HTML5 Intermediate

Also Known As

ARIA aria-label aria-expanded role attribute screen reader

TL;DR

Accessible Rich Internet Applications attributes add semantic meaning to HTML elements for screen readers — supplementing native HTML semantics for custom widgets.

Explanation

ARIA (role, aria-label, aria-describedby, aria-expanded, aria-hidden, aria-live) enhances accessibility for non-semantic HTML. The first rule of ARIA: don't use ARIA if native HTML provides the semantics. role='button' on a div is inferior to a real <button>. aria-label provides a text alternative for elements without visible text. aria-expanded signals the open/close state of accordions and dropdowns. aria-hidden='true' removes decorative elements from the accessibility tree. Never remove focus without providing an alternative.

Diagram

flowchart TD
    HTML[Semantic HTML<br/>button input nav main] -->|native semantics| ACC[Accessibility Tree]
    ARIA[ARIA attributes<br/>role aria-label aria-expanded] -->|supplement| ACC
    ACC --> SR[Screen Reader<br/>NVDA JAWS VoiceOver]
    subgraph First Rule of ARIA
        NATIVE[Use native HTML first<br/>button not div with role=button]
        KBRD[Add keyboard handlers<br/>if using role=button on div]
    end
    BAD[div onclick] -.->|missing keyboard nav| BROKEN[Inaccessible]
    GOOD[button type=button] -->|built-in keyboard| WORKS[Accessible]
    style BROKEN fill:#f85149,color:#fff
    style WORKS fill:#238636,color:#fff

Watch Out

Incorrect ARIA usage can make accessibility worse — mismatched roles, missing keyboard support, or wrong states can mislead screen readers.

Common Misconception

Adding ARIA makes an element accessible — ARIA only adds semantics; keyboard interaction and focus management must be implemented separately. A div with role='button' still needs keydown handlers.

Why It Matters

Custom UI components (dropdowns, modals, tabs, sliders) are invisible to screen readers without ARIA — they appear as unannounced content that keyboard users cannot interact with.

Common Mistakes

  • role='button' on a div without keyboard handlers — screen reader announces button but Enter/Space don't work.
  • aria-hidden='true' on focusable elements — removes from accessibility tree but keyboard can still focus it.
  • aria-label on every element — not needed on elements with visible text; use aria-labelledby instead.
  • Not updating aria-expanded when opening/closing components — screen reader never announces state changes.

Avoid When

  • Using ARIA to replace native HTML elements that already provide correct semantics.
  • Adding ARIA attributes without implementing required keyboard interaction and state updates.
  • Applying aria-hidden to interactive or focusable elements.

When To Use

  • Building custom UI components like modals, dropdowns, tabs, and sliders.
  • Enhancing non-semantic HTML where native elements cannot provide required accessibility.
  • Communicating dynamic state changes to assistive technologies.

Code Examples

💡 Note
Shows how ARIA augments semantics but still requires proper keyboard handling and state management.
✗ Vulnerable
<!-- Custom dropdown — inaccessible:
<div class="dropdown" onclick="toggle()">Menu</div>
<div class="dropdown-items" style="display:none">
    <div onclick="select('home')">Home</div>  <!-- Not keyboard accessible -->
</div>
✓ Fixed
<!-- Accessible dropdown with ARIA:
<button
    aria-haspopup="true"
    aria-expanded="false"
    aria-controls="nav-menu"
    id="nav-trigger"
>Menu</button>
<ul id="nav-menu" role="menu" hidden>
    <li role="none">
        <a href="/" role="menuitem">Home</a>
    </li>
</ul>
<!-- JS: toggle aria-expanded and hidden; manage focus -->
<!-- Enter/Space/Escape/Arrow keys handled -->

Added 15 Mar 2026
Edited 28 Mar 2026
Views 46
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 2 pings S 0 pings M 0 pings T 1 ping W 1 ping T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T
No pings yesterday
Amazonbot 15 Perplexity 13 Google 4 Unknown AI 3 Ahrefs 2
crawler 33 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Use native HTML elements before ARIA — a <button> is always better than <div role='button'>; add ARIA only when HTML semantics are insufficient for custom components
📦 Applies To
javascript HTML5 web
🔗 Prerequisites
🔍 Detection Hints
div or span with onClick without role; custom dropdown without aria-expanded; modal without aria-modal and focus trap
Auto-detectable: ✓ Yes axe lighthouse wave eslint-plugin-jsx-a11y
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update

✓ schema.org compliant