React Collapse Guide: Smooth Collapsible Content & Examples
A practical, code-forward walkthrough for building collapsible sections and accordions with react-collapse — installation, API, animation tips, accessibility, and production-ready best practices.
Why choose react-collapse for collapsible content?
If you need collapsible content that feels native, reacts to dynamic heights, and keeps layout thrashing to a minimum, react-collapse is a pragmatic choice. It animates the height of content with physics-driven motion (via react-motion under the hood), which makes expansions and collapses feel smooth and natural instead of awkwardly snapping between fixed heights.
Beyond animation quality, react-collapse is intentionally minimal: it focuses on the collapse behavior and lets you control rendering and structure. That keeps bundle size small and integrates well with React’s controlled components model — ideal when you need a custom accordion, nested collapsibles, or conditional rendering for performance.
If you’d like a compact react-collapse tutorial that demonstrates the basics and a step-by-step example, this guide complements that article with best practices and production tips.
Getting started — installation and basic setup
Install react-collapse via npm or yarn. The package exports a Collapse component that accepts an isOpened boolean and animates children accordingly.
npm install react-collapse react-motion
# or
yarn add react-collapse react-motion
After installing, import the component and use it inside a controlled component. The library animates based on content height, so you don’t need to hard-code heights for most use cases.
Here’s a minimal example showing the installation and import pattern. This is sufficient to get a simple collapsible section running in a functional React component.
import React, { useState } from 'react';
import { Collapse } from 'react-collapse';
function SimpleCollapse() {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(v => !v)}>Toggle</button>
<Collapse isOpened={open}>
<div>Collapsible content goes here.</div>
</Collapse>
</div>
);
}
Note: react-collapse depends on react-motion for its spring animation. Keep both dependencies in your package.json to avoid runtime issues.
Core API, props, and a complete example
The main prop you’ll interact with is isOpened (boolean). When true, react-collapse expands the container to fit children; when false, it animates to zero height. There are additional props for advanced control, such as theme (for styling hooks) and springConfig to adjust the animation’s stiffness and damping.
Use a controlled pattern when building accordions or when multiple collapsibles must coordinate. Controlled components make it straightforward to persist UI state, animate consistently, and integrate keyboard navigation.
Here’s a slightly richer example: a controlled collapsible with lazy content rendering to improve performance.
import React, { useState } from 'react';
import { Collapse } from 'react-collapse';
function LazyCollapse() {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(v => !v)}>Toggle details</button>
<Collapse isOpened={open}>
<div>
{open ? <HeavyComponent /> : null}
</div>
</Collapse>
</div>
);
}
Key props at a glance (quick reference):
- isOpened — boolean: controls open/close
- springConfig — object: adjust
stiffnessanddamping - theme — object: optional className hooks for styling
Using lazy rendering inside the collapse (render children only when open) reduces DOM load and improves initial render speed — especially when collapsed content contains heavy subtrees.
Smooth animations, dynamic heights, and accessibility
react-collapse manages height transitions by measuring content and animating the wrapper height. Because it adapts to dynamic content, it’s ideal for lists, forms, or content that changes after asynchronous data loads. The motion is physics-based, which tends to look and feel better than linear CSS transitions.
For smoothness: avoid forcing layout during transitions (e.g., avoid reading layout properties like offsetHeight inside animation loops). If you need custom easing, adjust the springConfig to tweak stiffness/damping rather than layering CSS transitions on top of the height animation.
Accessibility isn’t automatic — you must wire ARIA attributes and keyboard interactions. Recommendations:
- Use
aria-expandedon the toggle button to reflect open/closed state. - Associate the button with its region using
aria-controlsand anidon the collapse content. - Keep focus handling predictable: when expanding to reveal a form, move focus into the region; when collapsing, return focus to the toggle.
Example of ARIA wiring for a toggle:
<button
aria-expanded={open}
aria-controls="details-region"
onClick={() => setOpen(!open)}
>Details</button>
<Collapse isOpened={open}>
<div id="details-region">...</div>
</Collapse>
That combination provides good screen-reader semantics and predictable keyboard navigation for users relying on assistive tech.
Customization, performance optimizations, and SSR
You can customize animation behavior via springConfig or by wrapping Collapse in CSS-styled containers. For a snappier feel on mobile, slightly reduce stiffness; for a bouncier feel, reduce damping. Test changes on real devices — perceived performance varies across hardware.
Performance tips:
1) Lazy render heavy children only when the section is open; 2) If you have long lists inside collapsibles, virtualize them (react-window/react-virtualized) to avoid large DOM trees; 3) batch state updates and avoid synchronous DOM reads during animation frames.
Server-side rendering (SSR) considerations: when rendering on the server, you typically want all collapses to be closed by default (to avoid measuring client-only DOM). Hydrate on the client and then apply your open states. If initial visibility matters for SEO, render content but hide via CSS and then initialize collapse state on the client to enable animation.
Finally, style-driven customization is straightforward: use your CSS or utility classes inside the collapsed content. Keep the Collapse wrapper minimal and let children handle visual presentation for easier theming across your app.
Building an accessible accordion and best practices
An accordion is just a set of collapsibles with coordinated state — typically only one section open at a time. Implement this by storing the index or id of the open panel in parent state and passing isOpened down to each Collapse instance.
When multiple panels are possible, preserve state keys so React can manage DOM nodes predictably. Avoid re-mounting inner content unnecessarily; prefer toggling visibility rather than unmounting when you need to preserve form inputs or scroll position.
Basic accordion pattern (pseudo):
const [openIndex, setOpenIndex] = useState(null);
items.map((item, i) =>
<div key={item.id}>
<button onClick={() => setOpenIndex(openIndex === i ? null : i)}>{item.title}</button>
<Collapse isOpened={openIndex === i}><div>{item.body}</div></Collapse>
</div>
)
Best practices checklist:
- Apply ARIA roles and labels to toggles and regions
- Keep transitions short (<400ms) for perceived snappiness
- Lazy load heavy contents and virtualize long lists
For ready-made patterns (accordion component, code examples, and a practical walkthrough), see this example article on implementing collapsibles with react-collapse: React accordion component & react-collapse example.
When not to use react-collapse
react-collapse is focused on animating height. If you need complex multi-property choreographies (scale + transform + opacity across multiple independent elements), a more comprehensive animation library (like Framer Motion) may be a better fit. Likewise, for ultra-simple toggles where CSS transitions suffice and you don’t need dynamic height measurement, CSS-only solutions are lighter-weight.
If your UI requires simultaneous cross-component timeline control, consider an animation system designed for coordinated timelines. But for form panels, FAQs, nested collapsibles, and accordions that primarily need height animation, react-collapse is concise and reliable.
Choose the tool that minimizes friction for your feature set. For many apps, react-collapse hits the sweet spot: small API surface, dynamic height support, and good-looking motion out of the box.
FAQ
1. How do I install and start using react-collapse?
Install with npm install react-collapse react-motion (or yarn). Import Collapse, then use isOpened to toggle. Example: see the installation and basic setup section above.
2. How can I make react-collapse animations smoother on mobile?
Tweak springConfig to reduce stiffness/damping for a faster feel; lazy-render heavy children; avoid layout reads during animation. Keep transitions under ~400ms for perceived snappiness.
3. How do I build an accessible accordion with react-collapse?
Coordinate state in a parent to control which panel is open, use aria-expanded on toggles, link toggles to regions with aria-controls, and manage focus when panels open/close.
Semantic Core (keyword clusters)
Primary, secondary, and clarifying keyword groups for on-page SEO and content optimization.
Primary (high intent)
react-collapse React collapsible content react-collapse tutorial React expand collapse react-collapse installation React accordion component
Secondary (medium frequency / intent)
react-collapse example React collapse animation react-collapse setup React collapsible section react-collapse customization React collapse library
Clarifying / LSI / long-tail
react-collapse FAQ React smooth collapse react-collapse getting started how to use react-collapse react-collapse isOpened prop react-collapse springConfig accessible react collapse accordion react-collapse lazy render example react-collapse SSR considerations react-collapse performance tips
