Skip to main content
Copy for LLM

Accordion

The <x-wirekit::accordion> component creates collapsible content sections with single or multiple open modes. It follows the WAI-ARIA Accordion pattern.

Accordion vs Collapsible vs FAQ — when to use which
  • Accordion (this component) — a coordinated group of panels with optional single-open behavior and card chrome. Opening one panel can close the others.
  • Collapsible — a single independent show/hide (a "read more", an advanced-options panel), or a stack of them with no coordination.
  • FAQ — this accordion, specialized for questions, that also emits FAQPage structured data derived from what it renders. Use it for a real question list instead of hand-building one here.

Usage

Single-Open Accordion

Width & Layout

The accordion fills its parent width. Control the width with Tailwind classes directly on the component:

<x-wirekit::accordion class="max-w-lg">
    …
</x-wirekit::accordion>

Modes

Single mode

Opening one item closes all others — similar to radio buttons.

Single-Mode Accordion

Multiple mode

Any combination of items can be open — similar to checkboxes.

Multiple-Open Accordion

With Icons

Use the header named slot to render custom header content with icons:

Accordion with Icons

Variants

The variant prop changes the container chrome. bordered (default) is a self-contained card; flush drops the outline so the accordion sits inline in page content (ideal for an FAQ block); separated turns each item into its own standalone card with a gap between them.

Flush variant

Separated variant

Size

size="lg" gives the trigger roomier padding and a larger title — useful for marketing pages and touch-first layouts.

Roomy (lg) accordion

Long Titles

When the accordion has a fixed width, long titles wrap naturally while the chevron stays aligned:

Accordion with Long Titles

Find in Page

A closed item's content stays findable by the browser's own search (Ctrl+F or ⌘+F). When a match lands in a closed item, the browser opens it, scrolls to it and highlights the text, and the item's header reports it as expanded. In single mode, the item that was open closes, the same as when its header is clicked.

Closed content is still out of sight, out of the tab order and hidden from screen readers until it opens. Turn it off for content that must stay closed until someone chooses to open it, such as the answer to a quiz question:

<x-wirekit::accordion :findable="false">
    <x-wirekit::accordion.item title="Show the answer">The answer is 42.</x-wirekit::accordion.item>
</x-wirekit::accordion>

This is a progressive enhancement. It works in browsers that support hidden="until-found"; in the rest, a closed item is hidden entirely and the browser search does not look inside it.

A closed until-found panel stays in the layout. It keeps its box, so getClientRects() and getBoundingClientRect() report it as visible while the screen is drawn correctly and the reader sees nothing. Playwright's own visibility notion is built on the same geometry.

That matters wherever you ask "is this open?" from outside the component:

  • In a test, read the hidden attribute, not the geometry. A test that measures the box reads every closed item as open, and the number it reports looks plausible enough not to question — that cost a reader half a day of hunting a browser-lane failure that was never there.
  • In your own styling, put padding and borders on the element inside the panel. On the panel itself they paint as an empty strip under every closed item. This component and collapsible both do exactly that, for exactly this reason.

Animation

A panel eases its height open and shut. Set :animate="false" to have it appear and disappear instantly instead.

<x-wirekit::accordion :animate="false">

The easing reads --transition-wk-duration from the element, so a theme that sets the duration to zero gets no motion without touching this prop. It is skipped entirely under prefers-reduced-motion: reduce — the panel still opens, it just stops sliding to say so.

Props

<x-wirekit::accordion>

Prop Type Default Description
mode string 'single' 'single' (only one open at a time) or 'multiple'
variant string 'bordered' 'bordered' (card with outline), 'flush' (inline, dividers only), or 'separated' (each item its own card)
size string 'md' Row density — 'md' or 'lg' (roomier padding + larger trigger text)
level int 3 Heading level (1–6) each item's trigger is wrapped in. Set it to match the surrounding outline — 2 directly under the page <h1>, 4 inside an <h3> section
findable bool true Let the browser's find in page search closed items and open the one a match lands in. See Find in Page
animate bool true Ease a panel's height open and shut. Skipped under prefers-reduced-motion: reduce. See Animation
scope string|null null Scoped personalization key

<x-wirekit::accordion.item>

Prop Type Default Description
id string|null auto-generated Stable identifier used for Alpine state and ARIA wiring
title string '' Header text (or use the header named slot)
scope string|null null Scoped personalization key

Accessibility

  • Each header is a heading containing a <button> (allows AT heading navigation). The level comes from the accordion's level prop and defaults to <h3> — set it so the accordion does not skip a level in the page's outline
  • Button: aria-expanded (dynamic), aria-controls (linked to panel)
  • Panel: role="region", aria-labelledby (linked to button)
  • Chevron rotates 180° when open — decorative, aria-hidden="true"
  • Arrow keys, Home and End move focus between the headers and open nothing on the way — a panel opens on Enter or Space, so a reader can pass through a long accordion without waiting for every panel to reveal itself
  • Those keys apply while focus is on a header. Inside an open panel they belong to the content, so Home still moves the caret to the start of a line in a field you put there

Keyboard Interaction

Key Action
Tab Move focus to the next accordion header
Shift+Tab Move focus to the previous accordion header
Enter / Space Toggle the focused panel
ArrowDown / ArrowUp Move between accordion headers
Home / End Move to the first / last header

Pitfalls

  • Don't nest accordions more than two levels deep. WAI-ARIA Authoring Practices warn that screen-reader users lose track of the hierarchy. Reach for <x-wirekit::tree-view> for genuinely nested data.
  • Don't auto-expand all panels on load. Defeats the disclosure pattern — if everything is open, the accordion is just a stack of headings. Open at most one initial panel.

Design Tokens

Token Used for
--color-wk-bg-elevated Accordion container background
--color-wk-border Outer border + per-item separator
--border-wk-width Border width
--radius-wk-lg Container border radius

Config Defaults

The defaults live in config/wirekit.php under components.accordion. Override them globally:

'components' => [
    'accordion' => [
        'mode' => 'multiple', // allow multiple items open by default
        'findable' => false,  // keep closed items out of the browser's find in page
        'animate' => false,   // panels appear instantly instead of easing their height
    ],
],

Further Reading

Updated in WireKit v2.66.0 (2026-10-13)

Was this page helpful?

Thank you for your feedback!

Voting requires cookies or local storage. What we store