Skip to content

ARIA attributes and roles

ARIA (Accessible Rich Internet Applications) is a set of HTML attributes that add meaning for assistive technologies. ARIA does not change how an element looks or behaves -- it changes how screen readers announce it.

Two guiding principles:

  1. The first rule of ARIA: do not use ARIA if native HTML can do the job. A <button> is already announced as a button. Adding role="button" to a <div> is a workaround, not a solution -- use <button> instead.
  2. ARIA is a promise. If you add role="button" to an element, you are promising that it behaves like a button (keyboard-focusable, activated with Enter and Space). If it does not, you have made accessibility worse, not better.

When you need ARIA

Native HTML covers most cases. You need ARIA when:

  • You have multiple landmarks of the same type and need to distinguish them (e.g., two <nav> elements)
  • You want to label an element that has no visible text (e.g., an icon-only button)
  • You need to hide decorative content from screen readers
  • You are building custom interactive widgets that have no HTML equivalent
  • You want to associate descriptions with elements (e.g., error messages with form fields)

Adding ARIA attributes in Silex

Silex lets you add any HTML attribute to any element through the Attributes section in the Data panel:

  1. Select the element
  2. Open the Element settings (gear icon) in the right panel
  3. Scroll to the Attributes section (below States and above Properties)
  4. Click the + button
  5. Enter the attribute name (e.g., aria-label) when prompted
  6. Set the value -- either a fixed value (type it directly) or a dynamic expression from a data source

This works for all ARIA attributes, role, tabindex, data-* attributes, and any other HTML attribute.

Common ARIA attributes

aria-label

aria-label provides an accessible name for an element when there is no visible text.

Use cases:

  • Icon-only buttons: A hamburger menu button with no visible text.
  • Add attribute: aria-label = Open menu
  • Screen reader announces: "Open menu, button"

  • Distinguishing multiple landmarks: Two <nav> elements on the same page.

  • Primary nav: aria-label = Primary navigation
  • Footer nav: aria-label = Footer links
  • Screen reader lists: "Primary navigation, navigation" and "Footer links, navigation"

  • Search form: A search input with no visible label.

  • Add to the form or input: aria-label = Search this site

Do not use aria-label when visible text exists. If a button says "Submit," aria-label is unnecessary -- the visible text is already the accessible name.

aria-hidden

aria-hidden hides an element from screen readers while keeping it visible on screen.

Use cases:

  • Decorative icons next to text (the text already conveys the meaning)
  • Visual separators (decorative lines, shapes)
  • Duplicate content that would be confusing if read twice

Add attribute: aria-hidden = true

Warning: Never use aria-hidden="true" on focusable elements (links, buttons, inputs). The element would be invisible to screen readers but still receive keyboard focus, creating a confusing "ghost" element.

aria-labelledby

aria-labelledby points to the id of another element that serves as the label.

Use case: A section with a visible heading that should also be the landmark's accessible name.

  1. Select the heading, add attribute: id = features-heading
  2. Select the section, add attribute: aria-labelledby = features-heading
  3. Screen reader announces: "Features, region" (using the heading text as the name)

This is preferred over aria-label when visible label text already exists -- it avoids duplication and stays in sync if the text changes.

aria-describedby

aria-describedby points to the id of an element that provides additional description.

Use case: Form field with an error message or help text.

  1. Add a text element: "Must be at least 8 characters." Give it id = password-help
  2. On the password input, add: aria-describedby = password-help
  3. Screen reader announces: "Password, edit text. Must be at least 8 characters."

See Accessible forms for more on form error messages.

aria-live

aria-live announces dynamic content changes to screen readers. When content inside an aria-live region changes, the screen reader speaks the new content.

Values:

Value Behavior
polite Waits until the screen reader finishes its current announcement, then speaks the update
assertive Interrupts the screen reader immediately. Use sparingly -- only for urgent messages
off No announcements (default)

Use case: A form submission confirmation that appears dynamically.

  1. Select the container where the confirmation message will appear
  2. Add attribute: aria-live = polite
  3. When the message content changes (e.g., "Thank you, your message has been sent"), the screen reader announces it

role

The role attribute overrides or adds semantic meaning. Most of the time, you should use semantic HTML tags instead.

Instead of... Use...
<div role="button"> <button> (Tag Name selector)
<div role="navigation"> <nav> (Tag Name selector)
<div role="main"> <main> (Tag Name selector)
<div role="heading" aria-level="2"> <h2> (Tag Name selector)

Cases where role is appropriate:

  • role="presentation" or role="none" -- remove semantic meaning from a structural element (rare)
  • role="tablist", role="tab", role="tabpanel" -- for custom tab interfaces built with JavaScript
  • role="alert" -- equivalent to aria-live="assertive" for urgent messages

You have a row of social media icons (SVG images) that link to your profiles. There is no visible text -- only icons.

  1. For each link:
  2. Use a Link element wrapping an Image
  3. The image is decorative (the link is what matters), so set alt to empty
  4. On the link element, add aria-label via the Attributes section:

    • aria-label = Follow us on Mastodon
    • aria-label = View our GitHub repository
    • aria-label = Join our community chat
  5. On each icon image:

  6. Add aria-hidden = true (the aria-label on the link already provides the name)

  7. Result: Screen reader announces "Follow us on Mastodon, link" for each one, skipping the decorative image.

Common mistakes

  • Using ARIA when HTML already works. Adding role="button" to a <button> is redundant. Adding role="button" to a <div> instead of using <button> is wrong -- the Div still won't be keyboard-focusable without extra work.
  • aria-hidden on interactive elements. A button with aria-hidden="true" is invisible to screen readers but still focusable -- a confusing dead end.
  • aria-label that duplicates visible text. If a button says "Submit," adding aria-label="Submit" does nothing useful. Worse, if you later change the button text but forget to update aria-label, they will conflict.
  • Forgetting that ARIA does not add behavior. role="button" does not make an element focusable or clickable. You still need tabindex="0" and keyboard event handlers. This is why using native HTML is always better.
  • aria-live="assertive" on everything. Assertive interrupts the user. Use polite for most updates. Reserve assertive for urgent messages like errors.

Learn more


Reference: common ARIA attributes
Attribute Purpose Common values
aria-label Accessible name when no visible text Any string
aria-labelledby Accessible name from another element's text ID of labeling element
aria-describedby Additional description ID of describing element
aria-hidden Hide from screen readers true, false
aria-live Announce dynamic changes polite, assertive, off
aria-required Mark field as required true, false
aria-expanded Whether a collapsible is open true, false
aria-current Current item in a set page, step, true
role Override semantic role alert, tablist, tab, tabpanel, none

Quiz

Q1: A navigation link uses an SVG icon with no text. How do you make it accessible?

  • A) Add alt text to the SVG
  • B) Add aria-label to the link via the Attributes section
  • C) Add role="link" to the SVG
Answer

B) Add aria-label to the link -- The link element needs an accessible name. aria-label provides it when there is no visible text. SVG elements don't have alt attributes (that's for <img>).

Q2: You have a <div> with role="button". A keyboard user presses Tab but the element is skipped. Why?

  • A) The role is wrong
  • B) The Div is not focusable by default -- role="button" does not add focusability
  • C) The browser does not support ARIA
Answer

B) ARIA does not add behavior -- role="button" tells screen readers it is a button, but does not make it focusable or clickable. Use a native <button> element (Tag Name selector) instead.

Q3: You add aria-hidden="true" to a close button in a dialog. What happens for screen reader users?

  • A) The button is properly hidden and they use Escape instead
  • B) The button is invisible to their screen reader but still receives keyboard focus, creating a confusing dead end
  • C) The dialog closes automatically
Answer

B) The button is focusable but invisible to the screen reader -- This is a dangerous combination. Never use aria-hidden on interactive elements. If you want to hide something from screen readers, it must also be removed from the tab order.

Edit this page on GitLab