Accordion Component â Astro
Accessible accordion with collapsible sections, single or multiple open states, and keyboard navigation
Accordion Component
An accessible accordion for collapsible sections. Supports single or multiple open panels and full keyboard navigation.
Props
items(array, required) - Array of objects withid,title, and optionalcontentid(string, optional) - Unique identifier for the accordionallowMultiple(boolean, optional) - Allow multiple panels open at once (default:false)defaultExpanded(string | string[], optional) - ID or array of IDs to expand by default (defaults to first item)class(string, optional) - Additional CSS classes
Item Structure
id(string, required) - Unique identifier for the itemtitle(string, required) - Heading text for the triggercontent(string, optional) - HTML content for the panel (alternative to using slots)
Basic Usage (Single Open)
By default only one panel is open at a time. Provide panel content as children in the same order as the items array:
---
import Accordion from '../../components/Accordion.astro';
---
<Accordion
items={[
{ id: 'one', title: 'Section one' },
{ id: 'two', title: 'Section two' },
{ id: 'three', title: 'Section three' },
]}
>
<div><p>Content for section one</p></div>
<div><p>Content for section two</p></div>
<div><p>Content for section three</p></div>
</Accordion> Multiple Panels Open
Set allowMultiple to true to allow multiple panels to be open at once:
<Accordion
allowMultiple
items={[
{ id: 'a', title: 'First' },
{ id: 'b', title: 'Second' },
{ id: 'c', title: 'Third' },
]}
>
<div><p>First panel content</p></div>
<div><p>Second panel content</p></div>
<div><p>Third panel content</p></div>
</Accordion> With Content Property
You can provide panel content directly in the item object:
Yes. Components follow WCAG 2.1 AA and use proper ARIA patterns.
The CSS is framework-agnostic. See the multi-framework documentation.
<Accordion
items={[
{ id: 'faq1', title: 'Question one', content: '<p>Answer one</p>' },
{ id: 'faq2', title: 'Question two', content: '<p>Answer two</p>' },
]}
/> Default Expanded
Control which panel(s) are open initially with defaultExpanded:
<Accordion
defaultExpanded="second"
items={[
{ id: 'first', title: 'First' },
{ id: 'second', title: 'Second' },
{ id: 'third', title: 'Third' },
]}
>
<div><p>First</p></div>
<div><p>Second</p></div>
<div><p>Third</p></div>
</Accordion> Features
- Collapsible sections - Expand and collapse panels with smooth transitions
- Single or multiple open -
allowMultiplecontrols whether only one or several panels can be open - Keyboard navigation - Arrow Up/Down, Home, End, Enter, and Space
- ARIA -
aria-expanded,aria-controls,region,aria-labelledby - Content from props or slots - Use
content(HTML string) or pass children for panel content - Theme-aware - Uses design system variables
Keyboard Navigation
- Arrow Down - Focus next trigger
- Arrow Up - Focus previous trigger
- Home - Focus first trigger
- End - Focus last trigger
- Enter / Space - Toggle focused panel
Svelte & Vanilla: Svelte ¡ Vanilla: same HTML and BEM as in Usage above; add minimal JS for expand/collapse.