Skip to content

Accordions

Settings
Theme, language, accessibility preferences.
<div class="accordion">
<details class="accordion-item">
<summary class="accordion-summary">Settings</summary>
<div class="accordion-content">
Theme, language, accessibility preferences.
</div>
</details>
</div>
Account
Name, email, password.
Notifications
Email digests, push, in-app banners.
Billing
Plan, payment methods, invoices.
<div class="accordion">
<details class="accordion-item">
<summary class="accordion-summary">
<i class="ti ti-user" aria-hidden="true"></i>
Account
</summary>
<div class="accordion-content">Name, email, password.</div>
</details>
<details class="accordion-item">
<summary class="accordion-summary">
<i class="ti ti-bell" aria-hidden="true"></i>
Notifications
</summary>
<div class="accordion-content">Email digests, push, in-app banners.</div>
</details>
<details class="accordion-item">
<summary class="accordion-summary">
<i class="ti ti-credit-card" aria-hidden="true"></i>
Billing
</summary>
<div class="accordion-content">Plan, payment methods, invoices.</div>
</details>
</div>
Already expanded
Visible without a click.
<details class="accordion-item" open>
<summary class="accordion-summary">Already expanded</summary>
<div class="accordion-content">Visible without a click.</div>
</details>
Part Renders Class
Accordion <div> accordion
Accordion.Item <details> accordion-item
Accordion.Summary <summary> accordion-summary
Accordion.Content <div> accordion-content

No props of its own — each part takes the native attributes of the element it renders, so open on Accordion.Item and name for a single-open group both come from <details>. State lives in the DOM; there is no controlled mode.

Class Effect
accordion Vertical stack. Rounds the first and last item and collapses the shared borders
accordion-item On <details>: bordered surface panel
accordion-summary Row trigger: 1rem/0.75rem padding, text-sm medium, hover tint, trailing chevron that rotates when open
accordion-content Body: 1rem/0.75rem padding, text-sm, divided from the summary by a top border

Built on <details>/<summary>, so the disclosure needs no JavaScript in either bundle: open starts an item expanded, and a shared name attribute makes a group single-open. The default marker is hidden and replaced by the CSS chevron.

The open/close is animated with interpolate-size: allow-keywords on the item plus a ::details-content transition, which lets height: 0 interpolate to auto; browsers without it toggle instantly. Closed content keeps content-visibility: visible so it still contributes intrinsic width — otherwise a shrink-to-fit parent would reflow narrower on close.