Collapsible
An interactive component that expands/collapses a panel.
When to Use
Use Collapsible when you need to:
- Show or hide a single section of supplementary content
- Build file-tree or hierarchical navigation structures
- Create settings panels that reveal advanced options
- Reduce visual clutter while keeping content accessible on demand
- Implement a single expandable FAQ or detail row
Default
A collapsible panel showing starred repositories. Click the toggle button to expand/collapse.
@peduarte starred 3 repositories
Basic
Simple text-based collapsible with an inline trigger and CSS-driven chevron rotation.
With Animated Icon
Settings panel with an animated chevron icon that rotates on open/close using controlled state.
Advanced Settings
FAQ Style
Multiple independent collapsible items styled as an FAQ section. Each item operates independently.
Nested
Collapsible items can be nested to create file tree or hierarchical navigation structures.
Project Files
UX & Design Guidelines
Visual Hierarchy
The trigger should clearly indicate that content is expandable. Use a chevron icon that rotates between states to communicate interactivity. Pair the icon with a descriptive label so users understand what will be revealed. Keep the trigger visually distinct from the content it controls.
Spacing & Layout
Add gap-2 between the trigger and content for compact layouts, or use pt-4 for more breathing room. When nesting collapsibles, indent child items with pl-6 to convey hierarchy. Use border and rounded-lg to visually group trigger and content together.
Responsive Behavior
Collapsible sections are especially valuable on mobile where screen space is limited. Consider starting sections collapsed on smaller viewports to reduce scrolling. Ensure trigger touch targets meet the minimum 44x44px recommendation. Use w-full on triggers in narrow containers to maximize the tappable area.
Animation & Transitions
Use the data-state attribute to style based on open/closed state. Apply transition-transform duration-200 for smooth icon rotations. CSS grid animations can provide fluid height transitions. Keep animation duration under 300ms to feel responsive without causing motion discomfort.
Accessibility
Keyboard Navigation
- Tab -- Move focus to the collapsible trigger
- Enter or Space -- Toggle the collapsible open/closed
- When nested, Tab moves through each trigger in DOM order
- Content inside an open collapsible is reachable via Tab in natural reading order
Screen Reader Support
- Trigger automatically receives
aria-expandedreflecting the current state - Content is hidden from the accessibility tree when collapsed via
aria-hidden - When using
asChildwith an icon-only button, always providearia-labelor asr-onlyspan - Disabled state is communicated via the
disabledattribute on the trigger
Focus Management
Focus stays on the trigger after toggling, so users can press Space or Enter again to collapse. Newly revealed content does not steal focus -- users tab into it naturally. Visible focus ring uses focus-visible:ring-[3px] on the trigger for clear keyboard indication.
Motion Preferences
Respect prefers-reduced-motion by using Tailwind's motion-safe: prefix on transition utilities. When reduced motion is preferred, animations should be disabled or replaced with instant state changes.
ARIA Attributes
{/* Uncontrolled collapsible with accessible trigger */}
<Collapsible>
<CollapsibleTrigger asChild>
<Button variant="ghost" aria-label="Toggle details">
<ChevronsUpDown className="h-4 w-4" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
Details content here
</CollapsibleContent>
</Collapsible>
{/* Controlled collapsible with descriptive label */}
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
<CollapsibleTrigger asChild>
<Button variant="outline" aria-expanded={isOpen}>
{isOpen ? "Hide" : "Show"} Advanced Settings
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
Settings content here
</CollapsibleContent>
</Collapsible>
{/* Disabled collapsible */}
<Collapsible disabled>
<CollapsibleTrigger asChild>
<Button variant="ghost" disabled>
Unavailable Section
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
This content cannot be toggled.
</CollapsibleContent>
</Collapsible>Related Components
Accordion
Vertically stacked collapsible sections with coordinated expand/collapse behavior.
Card
Container with header, content, and footer for grouping related information.
Sheet
Slide-out panel for larger content sections that overlay the main interface.
Tabs
Layered sections of content displayed one at a time for mutually exclusive views.
API Reference
The Collapsible component is composed of three parts: a root, a trigger, and a content container.
Collapsible
Root component that manages the open/closed state.
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | The controlled open state of the collapsible. |
| defaultOpen | boolean | false | The default open state when initially rendered (uncontrolled). |
| onOpenChange | (open: boolean) => void | — | Event handler called when the open state changes. |
| disabled | boolean | false | When true, prevents user interaction with the trigger. |
| className | string | — | Additional CSS classes to apply to the root element. |
CollapsibleTrigger
The interactive element that toggles the content visibility.
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Merge props onto the immediate child element instead of rendering a default button. |
| className | string | — | Additional CSS classes to apply to the trigger element. |
CollapsibleContent
The container for the content that is shown or hidden.
| Prop | Type | Default | Description |
|---|---|---|---|
| forceMount | boolean | false | Force mounting when more control is needed (useful for entry/exit animations). |
| className | string | — | Additional CSS classes to apply to the content container. |