Skip to content

Accordion A11Y

DodaTech 3 min read

title: "Accessible Accordion — Show/Hide Sections with Keyboard Support" description: "Learn how to build accessible accordion components using details/summary or ARIA with proper keyboard navigation and screen reader announcements." weight: 9 date: 2026-06-28 lastmod: 2026-06-28 tags: [accessibility, navigation]


Accessible accordions allow users to expand and collapse content sections using keyboard or screen reader, with clear state announcements and focus management.

## What You'll Learn

How to implement accordion patterns natively with details/summary or with ARIA, including proper keyboard navigation and state announcements.

## Why It Matters

Accordions organize large amounts of content into expandable sections. Without accessibility, screen reader users cannot tell if a section is open or closed.

## Real-World Use

An FAQ page uses an accordion for each question. A screen reader user tabs to "How do I reset my password?" The button announces "How do I reset my password, collapsed, button." The user presses Space to expand it.

## Native HTML Accordion

```html
<details>
  <summary>How do I reset my password?</summary>
  <p>Go to Settings > Account > Reset Password. Follow the email instructions.</p>
</details>

<details>
  <summary>How do I update my billing info?</summary>
  <p>Navigate to Settings > Billing to update your payment method.</p>
</details>

Custom Accordion with ARIA

<h3>
  <button aria-expanded="false" aria-controls="section1"
          id="accordion1-btn">
    How do I reset my password?
  </button>
</h3>
<div id="section1" role="region" aria-labelledby="accordion1-btn" hidden>
  <p>Go to Settings > Account > Reset Password.</p>
</div>

JavaScript for Custom Accordion

document.querySelectorAll('[aria-controls]').forEach(button => {
  button.addEventListener('click', function() {
    const panel = document.getElementById(this.getAttribute('aria-controls'));
    const isExpanded = this.getAttribute('aria-expanded') === 'true';
    this.setAttribute('aria-expanded', !isExpanded);
    panel.hidden = isExpanded;
  });
});

Accordion Groups

<!-- Accordion group where only one section is open at a time -->
<div role="region" aria-label="Frequently asked questions">
  <h3><button aria-expanded="false" aria-controls="faq1">Question 1</button></h3>
  <div id="faq1" hidden>Answer 1</div>

  <h3><button aria-expanded="false" aria-controls="faq2">Question 2</button></h3>
  <div id="faq2" hidden>Answer 2</div>
</div>

Common Mistakes

1. No aria-expanded on custom accordions

The button must have aria-expanded="true/false" to communicate state to screen readers.

2. Missing aria-controls

aria-controls on the button links it to the panel id, helping screen readers associate the control with the content.

3. Focus not managed on expand

When expanding, the content should be immediately available but focus stays on the button for continued browsing.

4. Using div as button without role

A div with an onclick is not a button. Use button elements or add role="button" and keyboard handlers.

5. No role=region on panels

Each panel should have role="region" with aria-labelledby referencing the button, giving the panel an accessible name.

Practice Questions

1. What attribute indicates an accordion section is open? aria-expanded="true" on the controlling button indicates the section is open.

2. What HTML element provides native accordion behavior? details with summary provides native accordion behavior with no JavaScript required.

3. What role should each accordion panel have? role="region" with aria-labelledby referencing the trigger button.

Challenge: Build an FAQ accordion with 5 questions. Use the native details/summary element. Test with keyboard and screen reader.

FAQ

When should I use details/summary vs custom ARIA?

Use details/summary for simple accordions. Use custom ARIA when you need complex group behavior (only one open at a time) or custom styling.

Can details/summary be styled?

Yes, but the triangle indicator (::details-marker) has limited styling support in some browsers. Use list-style: none and custom pseudo-elements.

How does a screen reader announce an accordion?

Button: 'Question text, collapsed, button.' When expanded: 'Question text, expanded, button.' Panel: 'region, Question text.'

Should accordions animate?

Yes, but ensure the content is immediately accessible. Animations should not delay content availability.

Can I nest accordions?

Yes, but avoid deep nesting. Nested accordions are confusing for all users, especially screen reader users.

Mini Project

Create an FAQ page with 10 questions in an accordion. Use native details/summary for 5 and custom ARIA for 5. Compare the accessibility of both approaches.

What's Next

Learn about Accessible Carousel patterns and how to make rotating content accessible for all users.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro