Disclosure & accordion

Show/hide regions toggled by a real button with aria-expanded; independently openable.

Disclosure / Accordion

The accessible name is the text a screen reader announces for a control — derived from its content, a <label>, aria-label, or aria-labelledby.

Placeholders vanish on input, fail contrast, and are not reliably announced. Always pair a visible <label> with the field.

WCAG 2.2 sets a 24×24 CSS-pixel minimum (2.5.8); this system targets a comfortable 44×44 for primary controls.

Using the disclosure accessibly

Use a disclosure to hide secondary content behind a toggle the user opens on demand — FAQs, optional details, or filter groups.

Do

  • Use a real <button> with aria-expanded and aria-controls pointing at the panel.
  • Hide the closed panel with the hidden attribute so it leaves the tab order.
  • Let each item open independently when grouping several into an accordion.

Don't

  • Don't use a <div> or link as the trigger — you lose Enter/Space and focus for free.
  • Don't force a single-open accordion; closing the user's panel just to open another is surprising.
  • Don't animate the chevron unconditionally — honour prefers-reduced-motion.

Build it right

  • Trigger is a native <button type="button">; Enter and Space toggle it with no extra script.
  • Keep aria-expanded in sync with the panel's open state on every toggle.
  • aria-controls references the panel's id; the panel uses hidden when closed.
  • An accordion is just independent disclosures — don't auto-collapse siblings.
  • Gate any chevron rotation behind @media (prefers-reduced-motion: no-preference).

The source CSS for this component lives in assets/css/components/disclosure.css.