Skip to main content
Laptop displaying HTML code using ARIA attributes such as aria-labelledby and aria-describedby inside a browser window

ARIA

Accessibility Semantics

AccessibilityWebsiteTechnicalUI/UX
Author
Steven Hsu
Published
Updated

ARIA stands for Accessible Rich Internet Applications. It is a set of attributes that helps communicate roles, states, properties, names, and relationships to assistive technologies when native HTML alone cannot fully describe an interface.

ARIA is most useful for custom components, dynamic content, interactive states, and application-like interfaces. It helps screen readers and other assistive technologies understand what an element is, what state it is in, and how it relates to other parts of the page.

ARIA should support good HTML, not replace it.

The safest rule is simple: use native HTML first. Add ARIA only when there is a specific accessibility gap that semantic HTML cannot solve by itself.

What ARIA Does

HTML already carries meaning.

A <button> tells the browser and assistive technologies that the element is a button. A <nav> identifies navigation. A <main> identifies the main content area. A form input with a proper <label> communicates what the field is for.

ARIA becomes useful when an interface includes custom components or dynamic behavior that native HTML cannot fully describe on its own.

For example, a custom accordion may need to tell assistive technologies whether a section is expanded or collapsed. A notification area may need to announce new content without forcing the user to move focus. A form field may need supporting description text or an error state.

ARIA can provide this missing accessibility layer through roles, properties, and states.

However, ARIA does not add visual styling, keyboard behavior, focus management, validation logic, or JavaScript functionality by itself. It only communicates accessibility semantics. The actual interaction still needs to be built correctly.

Native HTML Comes First

The first rule of ARIA is to avoid using ARIA when native HTML already provides the correct meaning and behavior.

Incorrect ARIA can make an interface less accessible because it changes what assistive technologies announce. If the ARIA semantics do not match the real visual or functional behavior, users receive false information.

This is why “No ARIA is better than bad ARIA” is an important accessibility principle.

For example, this is not ideal:

Wrong Aria Usage
<div role="button">Submit</div>

A real button is better:

Native HTML
<button type="submit">Submit</button>

The native <button> already provides the correct role, keyboard behavior, focus handling, and expected browser behavior. Rebuilding that behavior on a <div> creates unnecessary risk.

ARIA should be used when the accessibility information cannot be expressed clearly with HTML alone. It should not be used to compensate for poor structure, missing labels, broken focus order, or inaccessible JavaScript.

How ARIA Works

ARIA usually works through three types of information: roles, properties, and states.

ARIA Type

What It Does

Example

Roles

Describe what an element is.

role="dialog"

Properties

Describe relationships or characteristics.

aria-labelledby, aria-describedby, aria-controls

States

Describe the current condition of an element.

aria-expanded="true", aria-invalid="true"

A role tells assistive technologies what kind of interface element they are dealing with. A property explains a relationship or additional meaning. A state communicates something that can change as the user interacts with the interface.

For example, an accordion button may look like this:

In this example, aria-expanded tells assistive technologies whether the controlled content is open or closed. aria-controls identifies the related content area.

But the ARIA attributes alone do not open or close anything. JavaScript still needs to update the visibility and change aria-expanded when the user interacts with the button.

These attributes are useful when they match the real interface state. They become harmful when they are added without being updated, tested, or connected to actual behavior.

Accessible Names and Descriptions

One of the most common uses of ARIA is helping controls and regions communicate a clear accessible name or description.

An accessible name tells assistive technologies what something is called. An accessible description gives additional context.

For an icon-only button, aria-label can provide the missing name:

Icon Button ARIA
<button type="button" aria-label="Search">
  <svg aria-hidden="true">...</svg>
</button>

For a region with a visible heading, aria-labelledby is often better because it reuses visible text:

Pricing Section ARIA
<section aria-labelledby="pricing-heading">
  <h2 id="pricing-heading">Pricing</h2>
  <p>Compare available plans and features.</p>
</section>

For a form field with helper text, aria-describedby can connect the field to the explanation:

Form Field ARIA
<label for="email">Email address</label>
<input id="email" type="email" aria-describedby="email-help">
<p id="email-help">Use the email address connected to your account.</p>

The important distinction is this: ARIA should clarify the accessibility tree. It should not replace visible clarity.

If users need a visible label, provide a visible label. If assistive technologies need additional context, connect that context properly.

ARIA and Forms

Forms are one of the most common places where ARIA is misused.

In most cases, a proper <label> should come before ARIA. A visible label helps everyone, not only screen reader users.

This is the correct foundation:

label usage
<label for="first-name">First name</label>
<input id="first-name" name="firstName" type="text">

ARIA can then support additional context when needed:

Additional Context Using ARIA
<label for="password">Password</label>
<input
  id="password"
  name="password"
  type="password"
  aria-describedby="password-requirements"
>
<p id="password-requirements">
  Use at least 12 characters, including a number and a symbol.
</p>

If there is an error, the error message should be connected to the field:

Changing States With ARIA
<label for="password">Password</label>
<input
  id="password"
  name="password"
  type="password"
  aria-invalid="true"
  aria-describedby="password-error"
>
<p id="password-error">
  Password must include at least 12 characters.
</p>

This approach keeps the structure clear. The visible label tells all users what the field is for. ARIA adds extra context where necessary.

ARIA and Interactive Components

ARIA becomes more important when websites use custom interactive components.

Common examples include accordions, tabs, dialogs, menus, comboboxes, sliders, disclosure controls, and live notifications. These components often require more than a role. They also require correct keyboard interaction, focus management, state updates, and expected behavior.

A modal dialog is a good example.

Adding role="dialog" is not enough. A proper dialog also needs a clear accessible name, focus should move into the dialog when it opens, keyboard users should be able to close it, and focus should return to the triggering element when it closes.

The ARIA attributes describe the dialog. They do not complete the dialog behavior.

Without correct JavaScript and focus handling, the component may still be inaccessible.

Common ARIA Patterns

Some ARIA patterns appear frequently in modern websites and applications. These patterns should be handled carefully because they combine semantics, behavior, state, and keyboard interaction.

Accordion buttons should use native <button> elements where possible. aria-expanded should reflect the open or closed state, and aria-controls can point to the related panel. The state must update when the user opens or closes the panel.

These patterns are useful only when the behavior matches the semantics. If the ARIA pattern says one thing and the interface does another, accessibility gets worse.

ARIA Is Not a Fix for Bad Structure

ARIA cannot repair a page that has poor semantic structure.

If a page has no logical heading hierarchy, missing landmarks, unlabeled controls, broken keyboard navigation, or unclear content relationships, adding ARIA will not solve the underlying issue.

A well-structured page should already use semantic HTML:

Page with Semantic HTML
<header>
  <nav aria-label="Main navigation">
    ...
  </nav>
</header>

<main>
  <article>
    <h1>ARIA</h1>
    ...
  </article>
</main>

<footer>
  ...
</footer>

In this example, ARIA is used lightly. The aria-label helps distinguish the navigation area, but the main structure still comes from HTML.

This is the right balance.

ARIA, JavaScript, and State

Many ARIA attributes only make sense when they stay synchronized with the interface.

If a menu is visually open but aria-expanded="false" remains unchanged, assistive technologies receive the wrong state. If a form field shows an error visually but the input is not connected to the error message, some users may not know what needs to be fixed.

This is why ARIA and JavaScript often need to work together.

For an accordion, JavaScript should update both the visible panel and the ARIA state:

Accordion State ARIA
<button
  type="button"
  aria-expanded="false"
  aria-controls="panel-1"
>
  Shipping details
</button>

<div id="panel-1" hidden>
  Shipping information appears here.
</div>

When the panel opens, the script should remove hidden and update aria-expanded to true. When the panel closes, the script should restore hidden and update aria-expanded to false.

ARIA should always describe the current truth of the interface.

The most dangerous mistake is creating a mismatch between what users see and what assistive technologies announce.

Good ARIA requires consistency between markup, visual state, interaction state, and assistive technology output.

How to Use ARIA Properly

The safest approach is to start with semantic HTML, then add ARIA only where there is a specific accessibility gap.

Start With HTML

Use native semantics.

Choose the correct HTML element first. Use real buttons, links, labels, headings, landmarks, lists, and form controls before adding ARIA. Native elements already include many accessibility behaviors.

Start With HTML

Use native semantics.

Choose the correct HTML element first. Use real buttons, links, labels, headings, landmarks, lists, and form controls before adding ARIA. Native elements already include many accessibility behaviors.

This process keeps ARIA practical. The goal is not to add more attributes. The goal is to make the interface more understandable and usable.

Best Practices for ARIA

ARIA works best when it is precise, minimal, and tied to real behavior.

Prefer Native Elements

Use native HTML elements whenever possible. A real <button> is better than a <div> with role="button". A real <label> is better than relying only on an ARIA label. Native elements already include built-in semantics and expected interaction behavior.

Keep Names Visible When Possible

Visible labels are usually better than hidden labels because they help everyone. Use aria-label for cases where visible text is not available, such as icon-only controls. Use aria-labelledby when visible text already exists and can label the element.

Update States Dynamically

State attributes such as aria-expanded, aria-selected, aria-invalid, and aria-pressed must reflect the current interface state. If JavaScript changes the UI, it should also update the relevant ARIA state.

Avoid Overusing Roles

Do not add roles to native elements that already communicate the right meaning. Extra roles can create confusion, especially when the role conflicts with the element’s actual behavior.

Be Careful With aria-hidden

Use aria-hidden="true" only when content should be hidden from assistive technologies. Do not use it on focusable elements, meaningful content, or anything users need to understand the page.

Test Interactive Components

Custom components should be tested with keyboard navigation and assistive technology behavior. Focus order, escape behavior, tab behavior, state announcements, and error messages all matter.

Why ARIA Matters

ARIA matters because modern websites are no longer made only of static documents.

They include dynamic menus, filters, modals, tabs, alerts, forms, dashboards, booking engines, data tables, and application-like interfaces. Without proper accessibility semantics, these experiences can become confusing or unusable for people relying on assistive technologies.

But ARIA only works when it is used with discipline.

It should be precise, minimal, and tied to real behavior. The best accessibility foundation is still clean HTML, logical structure, visible labels, keyboard support, predictable interaction, and good content hierarchy.

ARIA is not the foundation of accessibility. It is an enhancement layer for situations where native HTML needs help.

When used properly, it makes complex interfaces clearer. When used carelessly, it creates false information.

What Good ARIA Looks Like

Good ARIA is almost invisible.

It does not flood the page with attributes. It fills specific accessibility gaps where native HTML cannot fully communicate the interface.

A strong ARIA implementation usually has:

  • Native HTML wherever possible
  • Clear accessible names
  • Visible labels where useful
  • Connected descriptions and error messages
  • Accurate roles only when needed
  • States that update with the interface
  • Keyboard support for custom controls
  • Focus management for dialogs and overlays
  • Careful use of live regions
  • Testing beyond automated tools

The goal is not to add more ARIA. The goal is to make the interface honest, understandable, and usable.

Final Thoughts

ARIA is powerful because it helps complex interfaces communicate meaning to assistive technologies. But that power needs discipline.

Used well, ARIA clarifies roles, states, relationships, and dynamic behavior that native HTML cannot fully describe. Used badly, it can misrepresent the interface and make the experience worse for the people it is supposed to help.

The safest path is simple: start with semantic HTML, use ARIA only when there is a real accessibility gap, keep states synchronized, support keyboard interaction, and test the actual experience.

ARIA should make the interface more truthful, not more complicated.

Frequently Asked Questions

Practical answers about ARIA, semantic HTML, accessible names, states, forms, dialogs, and assistive technology.