Accordion
Reveal one region at a time. The trigger is a button. The content is a region labelled by that button. Do not nest by default.
Spec
- Trigger is a
<button>witharia-expandedandaria-controls. - Chevron rotates 90° in 160ms (
transform). - Content sits in a slot inside
role="region"witharia-labelledbypointing at the trigger. - Open/close animates
grid-template-rowsfrom0frto1fr— 280ms enter, 160ms exit,--ease-out. - Reduced motion: instant. No height trick that still interpolates.
- Do not nest accordions unless the job is genuinely recursive. Default is flat.
- One open at a time is allowed. Multi-open is allowed. Pick one per surface and keep it.
Live demo
Runnable controls. Not a screenshot. Paper / Ink in the header recolors tokens.
Metrics behind a trigger
p95 ingest is 1.4s, up 220ms vs the previous range. The spike started at 11:12 after a partition rebalance.
Remaining budget 14% for the 30-day window. Burn is 2.1× on the 1-hour window.
Last successful CSV export 12:04. Two failed retries at 12:06 — the feed did not respond.
Do / Don't
| Do | Don't |
|---|---|
| Button trigger, region labelled by it. | Clickable headings without a button. |
| Chevron as the only extra chrome. | Nest by default. |
| Animate grid rows, not measured height. | Slide another accordion open as a nested child. |
Motion
| Property | Duration | Easing | Trigger | Reduced motion |
|---|---|---|---|---|
chevron rotate(90deg) | 160ms --dur-exit | --ease-out | expand | instant |
grid-template-rows 0fr→1fr | 280ms enter / 160ms exit | --ease-out | expand / collapse | instant |
Accessibility
- Keyboard: Enter and Space on the trigger. Tab moves on.
- Name: the button's text is the name. The chevron is
aria-hidden. - Hit area ≥44px on the trigger.
- Color is not the only expanded cue — chevron rotation plus
aria-expanded. - These notes describe construction. They are not a guarantee of WCAG conformance. Validate with axe, keyboard, and operators. See Accessibility.
Related
- Tabs — sibling regions, one selected
- Motion
- Iconography —
chevron-downis notchevron-inline-end