Overview
Collapsible hides content that is real but secondary: advanced settings, a long explanation, details most visits do not need. One trigger, one panel, one decision.
Choose deliberately between hiding and shortening:
- Content most people never need — Collapsible. This component.
- Several related sections where opening one closes others — Accordion. It coordinates what Collapsible leaves independent.
- Content people must not miss — nothing hidden. Collapsing required information does not make it optional; it makes it invisible.
Anatomy
A collapsible has a trigger (a real button) and a panel whose visibility it controls. The panel mounts expanded or collapsed per the root's state, with height animation handled by the primitive.
Behavior
Keyboard.
The trigger is a native button, so it arrives in the natural tab order and announces its expanded state. Screen readers hear "collapsed"/"expanded" without extra ARIA on your part.
Independence. Each Collapsible stands alone. Toggling one never touches another — that coordination is exactly what you are choosing when you pick Accordion instead.
State. Controlled (open / onOpenChange) or uncontrolled. Controlled state is how you implement "expand all" or reopen a section after validation fails — see Don't do this.
Accessibility
The trigger exposes aria-expanded and controls the panel through the primitive's wiring; the panel's content is simply present or absent to assistive technology, matching what sighted users get. Trigger copy should preview what is inside ("Shipping options") rather than narrate the mechanism ("Click to expand").
Hidden panels keep out of the tab order while closed — focus skips genuinely unavailable controls instead of landing on ghosts.
Tokens handle dark mode and RTL mirroring automatically; the chevron rotates rather than swapping icons so reduced-motion users still get a state cue from geometry.
Installation
Usage
import {
Collapsible,
CollapsiblePanel,
CollapsibleTrigger,
} from "@/components/ui/collapsible";<Collapsible>
<CollapsibleTrigger>Shipping options</CollapsibleTrigger>
<CollapsiblePanel>{/* rates, delivery estimates */}</CollapsiblePanel>
</Collapsible>Don't do this
Hiding errors and required fields
// Bad
<Collapsible defaultClosed>
<CollapsibleTrigger>Billing address</CollapsibleTrigger>
<CollapsiblePanel>{/* required fields */}</CollapsiblePanel>
</Collapsible>Required input behind a closed panel fails invisibly: submit produces an error pointing at a field the person can see nowhere. If validation can fail inside a panel, open that panel programmatically when the error lands — controlled state exists precisely for this — or accept that this content does not belong in a collapsible at all.
Burying the summary in the panel
// Bad
<CollapsibleTrigger>Details</CollapsibleTrigger>// Good
<CollapsibleTrigger>Refund policy · 30 days, no questions</CollapsibleTrigger>"Details", "More", and "Advanced" make every collapsed section identical and cost a click just to tell apart. Put the one fact that helps someone decide whether to open — the policy's headline, the count of advanced options — into the trigger itself.
Examples
Advanced settings pattern
Command help pattern
API reference
Collapsible accepts Base UI Collapsible props:
Parts: CollapsibleTrigger, CollapsiblePanel.
See the Base UI Collapsible API.