Standards · ARIA

Role Widget

option

Marks an element as a selectable item inside a listbox. An option MUST be a descendant of a listbox (directly, or via aria-owns). Use native <option> inside <select>; reach for role="option" only when building a custom listbox or combobox popup.

When to use

Use <option> inside <select>. Native carries every behaviour for free.

role="option" is for items inside a custom role="listbox" — typically the popup of a combobox or a multi-select picker that native cannot style. Each option element MUST have a unique id so the parent combobox or listbox can reference it via aria-activedescendant.

If your option represents a checkbox-style choice in a multi-select listbox, set aria-selected="true". Use aria-checked only for the rare option-with-checkmark pattern (most multi-select listboxes use aria-selected).

Common failures

  • role="option" outside a role="listbox" parent. The screen reader announces an orphan option with no group context.
  • Missing id on an option that needs to be the aria-activedescendant target — the combobox cannot point to it.
  • Toggling a CSS .selected class without updating aria-selected. The visual and accessibility tree disagree.
  • aria-selected="false" on every option in a single-select listbox where one is meant to be the default. Set aria-selected="true" on one.
  • Options that are themselves buttons or links (<a role="option">). The option semantics override link semantics in the AT, but the click behaviour stays — confusing.

Example

<label id="lang">Language</label>
<ul
  role="listbox"
  aria-labelledby="lang"
  tabindex="0"
  aria-activedescendant="lang-2"
>
  <li id="lang-1" role="option" aria-selected="false">English</li>
  <li id="lang-2" role="option" aria-selected="true">Spanish</li>
  <li id="lang-3" role="option" aria-selected="false">French</li>
</ul>