@magic-spells/collapsible-content
v1.1.1
Published
Collapsible content web component
Maintainers
Readme
Collapsible Content Web Component
A lightweight, accessible Web Component for creating collapsible content sections. Perfect for FAQs, accordions, or any content that needs to be toggled.
Features
- No dependencies
- Lightweight
- Accessible (ARIA attributes, keyboard support, focus management)
- Smooth animations with
prefers-reduced-motionsupport - Smooth mid-animation reversal on rapid clicks
- Safe to import multiple times (no double-registration errors)
Installation
npm install @magic-spells/collapsible-contentimport '@magic-spells/collapsible-content';Or include directly in your HTML:
<script src="https://unpkg.com/@magic-spells/collapsible-content"></script>Usage
<collapsible-component>
<button type="button">Product Information</button>
<collapsible-content>
<div class="content-wrapper">
<h3>Details</h3>
<p>This product is made with 100% organic materials.</p>
</div>
</collapsible-content>
</collapsible-component>Start Expanded
Add the open attribute to start with content visible:
<collapsible-component>
<button type="button">Already Open</button>
<collapsible-content open>
<p>This content is visible by default.</p>
</collapsible-content>
</collapsible-component>Animation Speed
Animation duration scales dynamically with content height using a px/sec speed model. Short panels animate quickly, tall panels take proportionally longer — no fixed duration that feels too slow or too fast.
The default speed is 900 px/sec. Duration is clamped between 250ms and 800ms so animations always feel responsive. Tune it with the speed, min-duration, and max-duration attributes:
<!-- Default: 900px/sec -->
<collapsible-content>...</collapsible-content>
<!-- Faster -->
<collapsible-content speed="1200">...</collapsible-content>
<!-- Slower -->
<collapsible-content speed="80">...</collapsible-content>
<!-- Snappier minimum (150ms instead of 250ms) -->
<collapsible-content min-duration="0.15">...</collapsible-content>| Attribute | Default | Description |
| -------------- | ------- | ------------------------------------------ |
| speed | 900 | Animation speed in pixels per second |
| min-duration | 0.25 | Minimum animation duration in seconds |
| max-duration | 0.8 | Maximum animation duration in seconds |
Accordion Groups
Link collapsible components together with the group attribute so that opening one closes the others:
<collapsible-component group="faq">
<button type="button">Question One</button>
<collapsible-content>
<p>Answer one.</p>
</collapsible-content>
</collapsible-component>
<collapsible-component group="faq">
<button type="button">Question Two</button>
<collapsible-content>
<p>Answer two.</p>
</collapsible-content>
</collapsible-component>Items without a group attribute continue to work independently. All items in a group can be closed simultaneously — clicking the open item simply closes it.
| Attribute | Element | Default | Description |
| --------- | -------------------------- | ------- | -------------------------------------------------- |
| group | <collapsible-component> | — | Group name; items with the same name form an accordion |
Customization
Customize the animation easing with CSS custom properties:
collapsible-content {
--collapsible-easing: ease-in-out;
}| Property | Default | Description |
| ------------------------ | ---------- | ---------------------------------------------------- |
| --collapsible-duration | dynamic | Calculated from content height and speed attribute |
| --collapsible-easing | ease | Animation timing function |
Events
collapsible-error
Fired when the component is missing required children:
document.addEventListener('collapsible-error', (e) => {
console.error('Collapsible setup failed:', e.detail.error);
});Programmatic Control
Access the collapsed property on the <collapsible-content> element:
const content = document.querySelector('collapsible-content');
content.collapsed = true; // collapse
content.collapsed = false; // expand
console.log(content.collapsed); // get current stateAccessibility
This component follows WCAG guidelines:
aria-expandedon button indicates current statearia-controlslinks button to contentrole="region"andaria-labelledbyon contentaria-hiddenandinertwhen collapsed- Keyboard accessible (Space/Enter to toggle)
- Focus-visible styling for keyboard users
- Respects
prefers-reduced-motion
Browser Support
Modern browsers with Web Components support (Chrome, Firefox, Safari, Edge).
License
MIT
