Accordion

details.accordion[open]

Accordion — a disclosure, and a group of them.

Examples

A group, one open at a time

View “A group, one open at a time” as
Shipping
Orders leave the warehouse next day.
Returns
Thirty days, no questions asked.
Warranty
Two years on parts and labour.
<details class="accordion" name="faq" open>
  <summary class="accordion-trigger">Shipping</summary>
  <div class="accordion-panel">Orders leave the warehouse next day.</div>
</details>
<details class="accordion" name="faq">
  <summary class="accordion-trigger">Returns</summary>
  <div class="accordion-panel">Thirty days, no questions asked.</div>
</details>
<details class="accordion" name="faq">
  <summary class="accordion-trigger">Warranty</summary>
  <div class="accordion-panel">Two years on parts and labour.</div>
</details>

The shared name is what makes the group exclusive — the browser closes the siblings, with no script and no wrapper element. Remove it and each item is an independent collapsible.

A standalone collapsible

View “A standalone collapsible” as
Advanced options
Nothing here changes how the export is produced.
<details class="accordion">
  <summary class="accordion-trigger">Advanced options</summary>
  <div class="accordion-panel">Nothing here changes how the export is produced.</div>
</details>

Same component without name. That attribute is the entire difference between a collapsible and an accordion.

As page structure

View “As page structure” as

Installing

A single link tag is the whole integration.
<details class="accordion" name="chapters">
  <summary class="accordion-trigger"><h3>Installing</h3></summary>
  <div class="accordion-panel">A single link tag is the whole integration.</div>
</details>

A heading inside the summary is valid HTML and is what puts the item in the document outline. Use it when the accordion is the page, not an aside.

Tokens 21

Level 2, declared on .accordion itself. Set any of them on that selector to restyle this component without touching the skin.

Level 2 tokens declared by accordion
TokenDefault
--accordion-marker-colorvar(--color-on-surface-muted)
--accordion-marker-size0.4em
--accordion-panel-colorvar(--color-on-surface-muted)
--accordion-panel-font-sizevar(--font-size-sm)
--accordion-panel-padding-blockvar(--space-4)
--accordion-panel-padding-inlinevar(--space-4)
--accordion-trigger-font-familyvar(--font-secondary)
--accordion-trigger-gapvar(--space-3)
--accordion-trigger-padding-blockvar(--space-3)
--accordion-trigger-padding-inlinevar(--space-4)
--accordion-bgvar(--color-surface-raised)
--accordion-border-colorvar(--color-border)
--accordion-border-widthvar(--border-width)
--accordion-colorvar(--color-on-surface)
--accordion-radiusvar(--radius-box)
--accordion-durationvar(--duration-normal)
--accordion-gapvar(--space-1)
--accordion-panel-padding-block-startvar(--space-2)
--accordion-trigger-font-sizevar(--font-size-sm)
--accordion-trigger-font-weightvar(--font-weight-medium)
--accordion-trigger-hover-bgvar(--color-surface-sunken)

Variants and states

Variants

None. It is one shape, and the page does the rest.

Inside it

  • .accordion-trigger
  • .accordion-flush
  • .accordion-panel

State it reads

Read from the platform, never mirrored into a class that could disagree with it.

  • :focus
  • :hover
  • [open]
  • data-legacy

Before you ship it

What you have to do 5 requirements

  1. Give every item in a group the same name. A typo does not error; it quietly produces an item that opens on its own.
  2. name and open conflict: only the last open item in a named group stays open. Mark at most one.
  3. When the accordion is page structure rather than an aside, put heading content inside the summary — <summary class="accordion-trigger"><h3>… is valid HTML and is what puts the item in the document outline. The reset already makes the heading inherit its surroundings.
  4. A panel holding more than one block of copy wants .prose on it: the reset zeroes margins, so bare <p> siblings inside a panel sit flush together. .prose also restores full-contrast body colour over the panel's muted default, which is what you want for real running text.
  5. .accordion clips its own corners with overflow: hidden, so an overlay inside a panel must be one the browser promotes to the top layer (popover, <dialog>); an absolutely positioned one will be cut off.

src/css/components/accordion.css · npx mostlycss add accordion