ARIA Roles — Complete Guide
In this tutorial, you will learn about ARIA Roles. We cover key concepts, practical examples, and best practices to help you master this topic.
ARIA roles define the type of UI element a custom component represents, telling assistive technologies whether an element is a button, navigation landmark, dialog, tab panel, or other widget type.
What You'll Learn
- The six categories of ARIA roles
- Landmark roles and how to use them
- Widget roles for interactive components
- Abstract roles and why you rarely use them directly
- Document structure roles
- How to choose the correct role for your component
Why It Matters
- Roles are the foundation of ARIA — they tell screen readers what an element is
- Incorrect roles confuse assistive technologies and mislead users
- Landmark roles improve navigation for all assistive technology users
- Understanding role categories helps you choose the right role
Real-World Use
- A custom search interface uses search landmark role
- A modal dialog uses dialog role with aria-modal
- A tabbed product detail section uses tablist, tab, and tabpanel roles
- A news article uses article role within the main content
flowchart LR A[ARIA Roles] --> B[Widget Roles] A --> C[Landmark Roles] A --> D[Document Structure] A --> E[Abstract Roles] B --> F[Interactive Components] C --> G[Page Regions] D --> H[Content Types]
Understanding ARIA Roles
ARIA roles are the most important part of the ARIA specification. They categorize elements into types that assistive technologies can recognize and communicate to users.
When you add role="button" to a <div>, you are telling screen readers: "Treat this element as if it were a button." The screen reader will announce it as a button and expect button-like behavior (responding to Enter and Space keys).
Role Categories
There are six categories of ARIA roles:
Widget Roles: Represent interactive controls that users can manipulate. Examples: button, checkbox, slider, tab, menuitem, progressbar.
Composite Widget Roles: Widgets that contain other widgets. Examples: tablist, menu, listbox, grid, tree.
Landmark Roles: Identify regions of a page for navigation. Examples: navigation, banner, main, complementary, contentinfo, search, form.
Document Structure Roles: Describe the structure of content. Examples: article, heading, list, paragraph, table, tooltip.
Live Region Roles: For dynamic content that changes. Examples: alert, log, status, timer, marquee.
Abstract Roles: Used by the specification itself, not meant for developers. Examples: widget, input, range, section, structure.
Landmark Roles
Landmark roles help screen reader users navigate between major sections of a page. Most screen readers provide keyboard shortcuts to jump between landmarks.
<body>
<header role="banner">
<!-- Site title and logo -->
</header>
<nav role="navigation" aria-label="Main">
<!-- Primary navigation -->
</nav>
<main role="main">
<!-- Primary content -->
</main>
<aside role="complementary" aria-label="Related articles">
<!-- Sidebar content -->
</aside>
<footer role="contentinfo">
<!-- Copyright and links -->
</footer>
</body>
Note: Native HTML5 elements like <header>, <nav>, <main>, <aside>, and <footer> already have implicit landmark roles. The role attributes above are shown for illustration but are redundant when using the correct HTML elements.
Code Example: Choosing the Right Role
<!-- A custom dropdown that behaves like a listbox -->
<div class="custom-dropdown">
<button role="combobox"
aria-haspopup="listbox"
aria-expanded="false"
aria-controls="fruit-listbox"
id="fruit-combobox">
Select a fruit
</button>
<ul role="listbox"
id="fruit-listbox"
aria-labelledby="fruit-combobox"
hidden>
<li role="option" aria-selected="false" id="opt1">Apple</li>
<li role="option" aria-selected="false" id="opt2">Banana</li>
<li role="option" aria-selected="false" id="opt3">Cherry</li>
</ul>
</div>
Expected output: Screen readers identify this as a combobox. Users hear "Select a fruit, combobox, collapsed". Opening it reveals a listbox with three options. The role hierarchy correctly conveys the widget structure.
Code Example: Dialog Role
<div role="dialog"
aria-modal="true"
aria-labelledby="dialog-title"
aria-describedby="dialog-desc"
style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5);">
<div style="background:white; padding:2rem; max-width:500px; margin:4rem auto;">
<h2 id="dialog-title">Confirm Order</h2>
<p id="dialog-desc">You are about to place an order for $49.99.</p>
<button onclick="closeDialog()">Cancel</button>
<button onclick="confirmOrder()">Confirm</button>
</div>
</div>
Expected output: Screen readers announce "Confirm Order, dialog". The aria-modal attribute prevents interaction with content behind the dialog. aria-describedby provides additional context: "You are about to place an order for $49.99."
Code Example: Application Role (Use Sparingly)
<!-- Application role — only for complex widgets -->
<div role="application" aria-label="Spreadsheet editor">
<div role="grid" aria-label="Data grid">
<div role="row">
<div role="gridcell" tabindex="0">Cell A1</div>
<div role="gridcell" tabindex="-1">Cell B1</div>
</div>
<div role="row">
<div role="gridcell" tabindex="-1">Cell A2</div>
<div role="gridcell" tabindex="-1">Cell B2</div>
</div>
</div>
</div>
Expected output: The role="application" tells screen readers to pass all keyboard events to the application, disabling normal browsing mode shortcuts. This is appropriate for complex widgets like spreadsheets but should be avoided for standard web content because it breaks normal navigation.
Common Mistakes
- Using
role="application"on the entire page — This disables screen reader browsing mode, making normal navigation impossible. Only use it for specific widgets that need full keyboard control. - Applying landmark roles to non-landmark elements — Random divs with
role="banner"create confusing landmark navigation. - Conflicting implicit and explicit roles — Adding
role="heading"to an<h2>is redundant but not harmful. Addingrole="button"to an<a>changes its semantic meaning. - Omitting required child roles — A
tablistmust containtabchildren. Alistboxmust containoptionchildren. Amenumust containmenuitemchildren. - Using presentation role incorrectly —
role="presentation"removes semantic meaning but should only be used when the visual design requires it, not as a general fix. - Forgetting that HTML5 elements have implicit roles — A
<nav>already hasrole="navigation". A<footer>hasrole="contentinfo". Adding redundant ARIA is unnecessary. - Not testing roles with actual screen readers — Some roles behave differently across screen readers. Always test the actual behavior, not just the specification.
Practice Questions
- Name the six categories of ARIA roles. Widget, composite widget, landmark, document structure, live region, and abstract.
- What landmark roles are available and what do they represent? banner (site header), navigation (nav links), main (primary content), complementary (sidebar), contentinfo (footer), search (search functionality), form (form region).
- When should you use
role="application"? Only for complex widgets like spreadsheets, text editors, or drawing tools where normal screen reader browsing mode would interfere with interaction. - Why is it bad to add
role="button"to a<div>when you could use<button>instead? Native HTML elements have built-in keyboard handling, focusability, and Accessibility. Using a div requires manually implementing all of these, increasing code complexity and the chance of bugs. - Challenge: Build a custom toolbar component with
role="toolbar"containing buttons withrole="button"and a color picker withrole="radiogroup". Implement Arrow key navigation within the toolbar.
FAQ
{{< faq "What is the difference between role=\"presentation\" and role=\"none\"?" "They are identical. role=\"none\" is a newer, more intuitive name for the same concept. Both remove the element's semantic meaning from the accessibility tree." >}}Mini Project
Build a fully accessible custom file tree widget (similar to a file explorer sidebar). Use role="tree" for the container, role="treeitem" for each node, aria-expanded for collapsible folders, aria-selected for the selected item, and aria-setsize/aria-posinset for the position in the tree. Implement keyboard navigation: Arrow keys to navigate, Right to expand, Left to collapse, Enter to select. Include at least 3 levels of nesting.
What's Next
Continue with Lesson 8: ARIA Properties and States to learn how to convey dynamic information about component states to assistive technologies.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro