Skip to content
Pandus

Accessible accordion

Updated October 14, 2026 · 5 min read

Accordions keep long pages manageable: FAQ, delivery and returns, product details, filter groups. The APG defines one as "a vertically stacked set of interactive headings that each contain a title, content snippet, or thumbnail representing a section of content" — the headings show or hide their panels. This page shows the correct markup. It is part of the accessible UI patterns series.

When to use an accordion

  • Several independent sections where users want only one or two: FAQ, size and care, shipping and returns.
  • Mobile layouts where tabs do not fit.
  • Filter groups in a category sidebar.

Do not hide essential information in a closed panel when most users need it — price, availability and main product data belong in the open page.

Relevant WCAG criteria

Code example

<!-- APG accordion: heading > button, panel controlled by the button -->
<h3>
  <button type="button" id="acc-shipping" aria-expanded="true" aria-controls="panel-shipping">
    Shipping and delivery
  </button>
</h3>
<div id="panel-shipping">
  <p>Orders placed before 2 pm are shipped the same working day.</p>
</div>

<h3>
  <button type="button" id="acc-returns" aria-expanded="false" aria-controls="panel-returns">
    Returns
  </button>
</h3>
<div id="panel-returns" hidden>
  <p>You can return items within 30 days.</p>
</div>

<!-- Native alternative for independent sections -->
<details>
  <summary>Care instructions</summary>
  <p>Machine wash at 30 °C.</p>
</details>

Notes from the APG accordion pattern:

  • The title of each header is in an element with role button, which is wrapped in a heading with an appropriate level, and the button "is the only element inside the heading".
  • aria-expanded is true when the panel is visible, false when it is hidden; aria-controls references the panel.
  • If a panel is open and the accordion does not allow it to be collapsed, its button has aria-disabled="true".
  • Each panel may have role="region" with aria-labelledby pointing to its button. This is optional, and the APG advises against it when many panels can be expanded at once (about six or more), because it creates too many landmarks.
  • The script toggles aria-expanded and the hidden attribute. Rotate the chevron with CSS based on [aria-expanded="true"] so the visual state cannot get out of sync.

details and summary give you the button, the state and the keyboard behaviour without any script. They are a good fit for FAQ and care instructions; use the ARIA version when the section titles must also be headings in the page structure.

Keyboard interaction

From the APG accordion pattern:

Key Function
Enter or Space On a collapsed header: expands its panel (and, if only one may be open, collapses the other). On an expanded header: collapses it, if the accordion allows that
Tab Next focusable element; all headers and focusable content in open panels are in the tab sequence
Shift + Tab Previous focusable element

Common mistakes on online shops

  • Clickable div headers with a chevron icon — no button, no state, no keyboard.
  • The heading inside the button or the button wrapping the whole panel, which breaks the heading structure.
  • aria-expanded set once and never updated.
  • Closed panels hidden with max-height: 0 but their links still receive focus.
  • FAQ questions styled as headings but marked up as p or span, or headings that skip levels.
  • Only the small "+" icon is clickable, not the title.
  • Filter accordions that reload the page when opened, losing focus.

What automated checks catch vs manual testing

Automated (axe-core rule) What it finds
button-name Header buttons without a name
summary-name summary elements without a name
aria-valid-attr-value Invalid aria-expanded values, aria-controls pointing to missing IDs
empty-heading, heading-order Empty headings, skipped heading levels (advice)
nested-interactive Links or buttons inside the header button
aria-hidden-focus Focusable links inside a panel hidden with aria-hidden
landmark-unique Many region panels with the same name (advice)

All are cards in our rule library. Manual testing: open and close every section with Enter and Space, check that a screen reader announces "collapsed" and "expanded", that closed panels cannot receive focus and that the state icon is visible in both themes and at 200% zoom.

Run the free one-page check. It is an automated check, not a full audit.

Frequently asked questions

How do I build an accessible accordion?

Put each section title in a heading, and inside the heading a button with aria-expanded and aria-controls that shows or hides the panel. That is the APG accordion pattern. Native details and summary elements are a simpler alternative for independent sections.

Which keys does an accordion need?

Enter or Space on a header button opens or closes its panel, and Tab and Shift + Tab move through the headers and any links in open panels. No arrow keys are required.

Should each accordion panel have role="region"?

It is optional. The APG says to avoid it when many panels can be open at the same time, around six or more, because it creates too many landmarks.

Is content in a closed panel a problem for accessibility?

No, content in a closed panel is fine as long as the button is reachable and announces its state. The content must be hidden properly, for example with the hidden attribute, so that it cannot receive focus while closed.

Can an automated check test an accordion?

It finds header buttons or summary elements without a name, empty headings, invalid aria-expanded values and aria-controls pointing to missing IDs. Whether the state changes and the panel opens with the keyboard needs a manual test.

Sources

  • W3C WAI, APG Accordion pattern: https://www.w3.org/WAI/ARIA/apg/patterns/accordion/
  • W3C WAI, APG Disclosure pattern: https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/
  • WHATWG, HTML Living Standard, interactive elements (details and summary): https://html.spec.whatwg.org/multipage/interactive-elements.html