designmotionhq

interaction

Accordion Disclosure

One accordion glides open, the other jumps — four small rules separate them.

Key insights

  • You can't animate height: auto — the transition just snaps. Use display: grid with grid-template-rows going from 0fr to 1fr, or measure scrollHeight and animate to a pixel value.
  • Drive the chevron rotation from the same timing curve as the panel. Even ~10 frames of lag between the two reads as broken, not smooth.
  • Decide single vs multi open: an accordion lets one panel open at a time, a disclosure lets many stay open. Sequential steps stay single; FAQ lists let several breathe.
  • The header is a <button>, not a <div>. Wire aria-expanded to reflect state and aria-controls to point at the panel, so Enter/Space toggle it and the focus ring shows.
  • When an item near the bottom expands, anchor the tapped header so the list doesn't jump under the user, and stagger the revealed content in.

Do / Don't

  • Do: Drive chevron rotation and panel height from one shared timing curve so they move as a unit
  • Do: Render the header as a real <button> with aria-expanded and aria-controls wired to the panel
  • Do: Match open behavior to content — one-at-a-time for steps, many-open for FAQ lists
  • Don't: Animate height: auto and expect a transition — use grid rows or a measured pixel height
  • Don't: Let the chevron trail the panel; even a few frames of lag feels janky
  • Don't: Let the list scroll-jump when a lower item expands — keep the tapped header anchored

Get the next pattern first

New breakdowns land in your inbox before anywhere else.

One new pattern breakdown per week. No spam, unsubscribe anytime.

Related patterns