The WAI-ARIA specification opens with what it calls the “first rule of ARIA use”: if you can use a native HTML element or attribute with the semantics and behavior you require already built in, do that instead. ARIA does not fix broken HTML — it supplements what the browser’s accessibility tree exposes to assistive technology. Misapplied, it actively degrades the experience for screen reader users. Applied correctly, it fills genuine gaps where HTML cannot express the needed role, state, or property on its own.

Understanding the difference between “native HTML is enough” and “ARIA is required” is the practical skill this article is about. The clearest example of “native HTML is enough” is landmark structure — see our guide to ARIA landmark roles for how <header>, <nav>, <main>, and <footer> already carry the roles a developer might otherwise reach for role="banner" or role="navigation" to add manually.

Why ARIA Exists

Browsers expose a parallel representation of the DOM called the accessibility tree. Screen readers, braille displays, and other assistive technologies consume this tree — not the visual layout. Every HTML element maps to a default ARIA role implicitly. A <button> has an implicit role of button. A <nav> has an implicit role of navigation. A <main> has main. These mappings are defined in the HTML-AAM specification and are implemented by browsers natively.

ARIA exists to handle situations that native HTML cannot: custom widgets built from <div> and <span> elements, dynamic content regions that update without a page reload, complex interactive components (date pickers, data grids, comboboxes) that have no HTML counterpart, and structural markup on elements where the default role is wrong for context.

The key constraint: ARIA changes what the accessibility tree exposes, but it does not change behavior. Adding role="button" to a <div> does not make it keyboard-focusable, does not make Enter or Space activate it, and does not wire up any of the expected interaction patterns. The behavior must be implemented separately in JavaScript. A <button> gives you all of that for free. This asymmetry is why the first rule of ARIA is more than a stylistic preference — it represents a meaningful reduction in implementation surface.

The Four Role Categories

The ARIA spec organizes roles into categories. Understanding the category tells you a great deal about what a role does and when it belongs.

Abstract Roles

Abstract roles like roletype, widget, and structure are base categories used internally to organize the taxonomy. They are not intended for authors and should never appear in markup. Browsers ignore or reject them.

Landmark Roles

Landmark roles divide a page into navigable regions. Screen reader users rely on landmarks for efficient navigation — most screen readers include a landmark list or shortcut keys that let users jump directly to the <main> content, skip to <nav>, or locate the <footer>. This is the equivalent of visual scanning for a sighted user.

The landmark roles, their native HTML equivalents, and when you need explicit ARIA:

RoleNative HTMLNotes
banner<header> (top-level only)Nested <header> elements do not get banner role implicitly
navigation<nav>Use aria-label when multiple <nav> elements exist
main<main>Only one per page
complementary<aside>
contentinfo<footer> (top-level only)Same caveat as banner
search<search> (HTML 2022+)Use role="search" if <search> support is insufficient for your baseline
form<form> with an accessible nameUnnamed <form> does not expose a landmark role
region<section> with an accessible nameUnnamed <section> has no landmark semantics

When you use the native element correctly, you get the landmark role for free. Where ARIA roles become necessary in practice:

Multiple navigation blocks. A page with a primary nav, a breadcrumb, and a footer nav has three <nav> elements. Without labels, screen readers announce all three as “navigation” with no way to distinguish them. The fix is aria-label, not a changed role: <nav aria-label="Primary">, <nav aria-label="Breadcrumb">. If you cannot use <nav> for some reason, <div role="navigation" aria-label="Primary"> is the fallback — but using <nav> is preferred.

The region landmark requires a name. A <section> element only exposes a landmark role when it has an accessible name via aria-label or aria-labelledby. An unnamed <section> is treated like a <div> in the accessibility tree. This surprises developers who expect section elements to behave like landmarks automatically.

The form role has the same requirement. A <form> element only maps to a form landmark when it has an accessible name. If the form is the sole purpose of a page (a login page, a checkout step), adding an aria-label or wrapping it with a visually-hidden <h2> connected via aria-labelledby makes the entire form navigable as a landmark.

Document Structure Roles

These roles describe the structure of content rather than interactive behavior. Most have native HTML equivalents: heading maps to <h1>–<h6>, list and listitem map to <ul>/<ol> and <li>, img maps to <img>.

Where document structure roles occasionally become necessary:

  • role="img" on a container element grouping several SVG icons or image elements that together represent a single concept, combined with aria-label to give the group a text alternative.
  • role="presentation" or role="none" to explicitly remove semantics from an element — for example, a layout table that should not be announced as a data table by screen readers.
  • role="separator" on a <hr> is implicit, but on a custom divider component built with a <div>, the explicit role may be necessary.

In most cases, the right move is to use the native element. The document structure roles serve as escape valves when the native element is unavailable or structurally impractical — legacy CMS output being a common real-world constraint.

Widget Roles

Widget roles are where ARIA earns its keep. These describe interactive UI components. The rule still applies — if there is a native HTML control, use it. But for patterns without native equivalents, widget roles (combined with correct keyboard interaction and state management) are how assistive technology understands what users are interacting with.

The ARIA Authoring Practices Guide (APG) from the W3C provides reference implementations for each widget pattern. Before building a custom widget, check the APG — it defines the expected keyboard behavior alongside the required ARIA markup. The two must be implemented together; the ARIA alone is not sufficient.

Tabs. There is no native HTML tab component. A tab interface requires role="tablist" on the container, role="tab" on each tab trigger, and role="tabpanel" on each panel. Tabs should be navigated with arrow keys within the tab list, not Tab key. The selected tab receives aria-selected="true". This is markup that cannot be expressed with native HTML alone.

Dialog and modal. role="dialog" on a modal container, with aria-modal="true" to signal that content behind the dialog is inert, and aria-labelledby pointing to the dialog’s heading. Focus must move into the dialog on open and return to the trigger on close. Focus must be trapped inside the dialog while it is open. Without these patterns implemented correctly, screen reader users may navigate into background content that is visually obscured.

Combobox. Custom autocomplete and select-with-search patterns require role="combobox" on the input, role="listbox" on the dropdown container, and role="option" on each choice. The aria-expanded state must be toggled when the list opens and closes. The aria-activedescendant attribute points to the currently focused option. This is a complex widget — the APG combobox pattern documents the full interaction model.

Tree and treegrid. Hierarchical navigation (file trees, nested navigation) has no native equivalent. role="tree", role="treeitem", and aria-expanded on nodes with children model the structure for assistive technology.

For more on how semantic HTML structure relates to accessibility tree output, the relationship between the two becomes relevant whenever widget roles are involved — the host element still carries its own default role, and overriding it requires deliberate markup.

The Naming Triad: role, aria-label, aria-labelledby, and aria-describedby

A role tells assistive technology what an element is. An accessible name tells it what the element is called. A description provides supplementary context.

  • aria-label provides a text label directly in the attribute value. Use it when no visible label text exists or when the visible text is insufficient.
  • aria-labelledby references the ID of another element that serves as the label. Prefer this when the label text is already visible on screen — it avoids duplication and keeps the source of truth in one place.
  • aria-describedby references supplementary text — error messages, format hints, additional instructions. It is announced after the role and name in most screen reader implementations.

The distinction matters practically. A search input with a visible <label> for “Search” and placeholder text showing the expected format should use <label> for the name (connected via for/id or wrapping) and aria-describedby pointing to a hint element for the format guidance. Combining both in a single aria-label is technically valid but loses the relationship between the visual label and the accessible name.

aria-label silences the element’s computed text content in most screen readers. Applying aria-label="Close" to a <button>Close</button> is redundant but harmless. Applying it to a <button aria-label="Dismiss notification">X</button> is correct and necessary — the visible text “X” is not meaningful to a screen reader user.

Live Regions

aria-live instructs assistive technology to announce dynamic content changes without requiring the user to navigate to that element. The value determines urgency:

  • aria-live="polite" — announces after the user finishes the current interaction. Appropriate for most status messages, search result counts, form validation feedback.
  • aria-live="assertive" — interrupts immediately. Reserve this for genuinely urgent information (session timeout warnings, critical errors). Overuse creates a disruptive experience.

aria-atomic="true" tells the screen reader to announce the entire region’s content when any part of it changes, rather than just the changed node. This matters when a status message like “3 results found” updates — announcing just “3” without context is not useful.

Live regions must exist in the DOM before the content is injected into them. A common mistake is creating the live region element and inserting the message simultaneously in JavaScript. Many screen readers miss the announcement because they have not yet registered the region as live. The region should be present — empty — on page load or component initialization.

<!-- Live region present before dynamic content is injected -->
<div role="status" aria-live="polite" aria-atomic="true" class="sr-only" id="search-status"></div>

<!-- Later, via JavaScript -->
document.getElementById('search-status').textContent = '12 results found for "parking sensors"';

role="status" is shorthand for an aria-live="polite" region with aria-atomic="true". role="alert" is shorthand for aria-live="assertive".

Common Mistakes Worth Naming Explicitly

role="button" on a <div> or <span>. This is the canonical example of ARIA misuse. The role change does not add keyboard focus, does not make Enter or Space trigger a click event, and does not give the element any of the other built-in behaviors of a <button>. Implementing all of that manually is more work than using <button> and overriding its default styles. Use <button>. The styling constraints on native buttons are not a reason to avoid them — CSS handles appearance independently of semantics.

Redundant roles. Adding role="navigation" to a <nav> element is harmless but signals a misunderstanding. The same applies to role="main" on <main>, role="heading" on an <h2>, and similar patterns. These add noise and may confuse developers inheriting the code.

aria-hidden="true" on focusable elements. Hiding an element from the accessibility tree while leaving it keyboard-focusable creates a broken experience — users can tab to something that screen readers treat as nonexistent. Either remove the element from the tab order (tabindex="-1") or do not apply aria-hidden.

Missing required owned elements. Some roles define required children. role="list" expects role="listitem" children. role="tablist" expects role="tab" children. role="tree" expects role="treeitem" children. Violating these ownership requirements produces unpredictable behavior across different screen reader and browser combinations. The ARIA spec’s role definitions document required owned elements for every widget role.

Overusing aria-label at the expense of visible labels. An input with only aria-label and no visible label works for screen reader users but fails sighted users with cognitive disabilities, voice control users who navigate by label text, and anyone who glances at a form before filling it in. Visible labels, connected correctly via <label> or aria-labelledby, serve both audiences.

When Native HTML Is Enough

For the majority of page content — headings, paragraphs, lists, links, buttons, form inputs, tables — native HTML elements carry the correct semantics without any ARIA augmentation. The practical test: if the element you are building has a direct HTML counterpart, use that counterpart. The browser’s implicit role mapping handles the rest.

Where ARIA is genuinely necessary: custom interactive widgets with no HTML equivalent, dynamic content regions that update in place, and specific cases where the default role of an element is semantically wrong for its context. The APG patterns library covers the canonical widget implementations — tabs, dialogs, comboboxes, menus, carousels — with full markup and keyboard interaction specifications.

The test for any ARIA addition is whether it communicates something to assistive technology that native HTML cannot. If native HTML communicates it already, the ARIA attribute is at best redundant and at worst contradictory. Understanding that distinction — through the accessibility tree, through screen reader testing, and through the spec itself — is what separates ARIA used as a tool from ARIA used as decoration.

For teams evaluating how web font loading strategy interacts with layout shifts that could disrupt live region announcements, the connection between rendering performance and accessibility experience is worth considering in dynamic UI contexts.