Accordion A11Y
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
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