References

Beginner-friendly references for web development, with live, editable examples.

The HTML aria-expanded attribute

ARIA Accessibility
In short

A control such as a <button> uses aria-expanded to tell assistive technology whether the content it opens is showing. The value is true when open and false when closed, and script has to flip it and show or hide the content as well.

Overview

Set on a control, aria-expanded says whether the content that control shows and hides is expanded or collapsed. It belongs on the focusable, interactive element that toggles the visibility of content in another element, so it goes on the button and not on the panel.

An element with nothing to expand should skip the attribute, since on most roles no value means it owns or controls nothing expandable, while false means collapsed content. So end nodes in a tree and rows with no child rows should leave it off.

Some HTML features report the state without ARIA. The open attribute of <details> is exposed on its <summary>, and a popovertarget button is exposed as expanded while its popover shows, with no attribute in the markup. Use them where they fit.

WAI-ARIA 1.2 narrowed the role list. It supports the state on application, button, checkbox, combobox, gridcell, link, listbox, menuitem, row, rowheader, tab and treeitem, plus inheritors such as switch.

The same version removed it from roles such as region, group, dialog and heading. Browsers drop it from the accessibility tree on those roles and on a plain <div>, so a panel marked this way reports nothing.

Syntax

<button aria-expanded="false" aria-controls="shipping">Shipping</button>
<div id="shipping" hidden>Orders leave within two business days.</div>

Values

Value
true | false | undefined

Example

Live example
<p style="margin:0 0 8px">Press a button to open or close its section.</p>
<div>
  <button type="button" aria-expanded="false" aria-controls="shipping">Shipping</button>
  <div id="shipping" style="padding:6px 0" hidden>Orders leave within two business days.</div>
</div>
<div style="margin-top:8px">
  <button type="button" aria-expanded="false" aria-controls="returns">Returns</button>
  <div id="returns" style="padding:6px 0" hidden>Send items back within 30 days for a refund.</div>
</div>
<p role="status" id="state" style="margin:10px 0 0">Both sections are closed.</p>
<script>
document.querySelectorAll('[aria-expanded]').forEach(function (button) {
  button.addEventListener('click', function () {
    const open = button.getAttribute('aria-expanded') !== 'true';
    button.setAttribute('aria-expanded', String(open));
    document.getElementById(button.getAttribute('aria-controls')).hidden = !open;
    document.getElementById('state').textContent = button.textContent + ' is ' + (open ? 'open' : 'closed') + ', so its aria-expanded value is ' + open + '.';
  });
});
</script>

Best practices

  • Flip aria-expanded and the content's visibility in one handler.
  • On a parent row in a treegrid, set it on the row itself. A value on a gridcell applies to that cell alone and doesn't stand in for the row.
  • Keep it off a rowheader in a plain table. The state only applies to interactive elements, so a rowheader that descends from a table should not use it.
  • Leave role="button" off <summary>. That role is unnecessary there and can stop the element from correctly exposing its state.

Frequently asked questions

Does aria-expanded go on the button or on the panel?
The aria-expanded attribute goes on the button or other control, not on the panel. When the control doesn't own the panel, reference it with aria-controls.
Does a details element need aria-expanded?
No, a summary in details doesn't need aria-expanded, because its state is already exposed. ARIA in HTML leaves the attribute off that element's allowed list, and Chrome and Firefox keep the real state when a value conflicts.
Why is my panel still hidden with aria-expanded=true?
Setting aria-expanded changes nothing on screen, so the panel stays as it was. Your script also has to remove the hidden attribute or change the panel's styles.
Can a link have aria-expanded?
Yes, link is one of the roles that support aria-expanded. A link that opens a submenu can carry it, with script updating the value.
Is aria-expanded required on a combobox?
Yes, aria-expanded is a required state of the combobox role. It must be true when the combobox is expanded and false when it's collapsed.
What should aria-expanded be on a closed menu button?
Use false, because a missing aria-expanded value strictly means there's nothing to expand. Omitting it while the menu is hidden is also allowed.