SHUTTERS
A Lightweight, Accessible JavaScript Accordion Component
Dependency-free accordion component with smooth CSS Grid animations, full ARIA accessibility, keyboard navigation, and customizable theming. Under 2KB gzipped.
Why Choose Shutters Accordion?
Shutters is a lightweight JavaScript accordion with zero external dependencies. The entire component — JavaScript and CSS combined — weighs under 2KB gzipped, making it one of the smallest accordion solutions available. Unlike jQuery-based accordion plugins or heavy UI frameworks, Shutters adds virtually no overhead to your page load time.
Accessibility isn't an afterthought — it's built into the core of Shutters. The component
automatically applies WAI-ARIA Accordion Pattern attributes — role="button",
tabindex="0", and aria-expanded — on every header at initialization,
so you never need to write them in your HTML. Full keyboard navigation
is supported via Enter, Space, Arrow Up, Arrow Down,
Home, and End keys, with visible :focus-visible indicators
for keyboard users.
Instead of using JavaScript-driven height calculations or the jittery max-height
hack, Shutters leverages CSS Grid's grid-template-rows transition
for buttery-smooth expand and collapse animations at 60fps. This approach is GPU-accelerated,
avoids layout thrashing, and works with dynamic content heights — no fixed pixel values needed.
On the JS side, Shutters uses event delegation — just one click listener
per container instead of one per header — keeping memory usage minimal even with many panels.
Get an accordion running in under 5 minutes. Shutters provides both ES Module
and UMD bundle formats, so it works with Vite, Webpack, Rollup, or a simple
<script> tag. The programmatic API offers open(),
close(), toggle(), openAll(), closeAll(),
and destroy() methods for full control. Subscribe to state changes with
on('shutters:open', callback) and on('shutters:close', callback).
Basic Accordion Demo
Shutters Accordion is a lightweight, dependency-free JavaScript accordion component that provides smooth expand/collapse functionality using modern CSS Grid animations and vanilla JavaScript. It's designed for easy integration into any web project — from static HTML pages to React, Vue, or Svelte applications. Install via npm, include via CDN, or add the source files directly.
Shutters uses the modern CSS Grid grid-template-rows transition
technique to animate content height from 0fr to 1fr. This avoids
the common pitfalls of max-height hacks or JavaScript-measured height animations.
The result is smooth, GPU-accelerated 60fps animations that work with any content height.
- Vanilla JavaScript with zero dependencies
- CSS Grid animations for smooth, jank-free transitions
- Full accessibility with auto ARIA setup and keyboard navigation (Arrow/Home/End)
- Event delegation — one listener per container for optimal performance
- Custom events (
shutters:open/shutters:close) for reactive integrations - Works with dynamic content — no fixed heights needed
Key features of Shutters Accordion include:
- Lightweight: Under 2KB gzipped — zero dependencies, pure vanilla JavaScript and CSS
- Accessible: WAI-ARIA accordion pattern with full keyboard navigation and screen reader support
- Smooth Animations: CSS Grid-based 60fps expand/collapse transitions
- Modular: Separate core functionality CSS from optional presentation theme
- Customizable: Theme via CSS custom properties — colors, timing, easing
- Auto-Close Mode: Optional single-panel-open behavior
- Programmatic API: open(), close(), toggle(), openAll(), closeAll(), destroy() methods
-
Custom Events: Subscribe to
shutters:openandshutters:closevia on()/off() - Event Delegation: One listener per container — optimal performance at any scale
- Universal: ES Module + UMD bundles — works with any build tool or plain HTML
Auto-Close Accordion Demo
In auto-close mode, only one accordion panel can be open at a time. Opening a new section automatically collapses the previously open one — ideal for FAQs and settings panels.
Auto-close mode ensures only one accordion panel is expanded at any time.
When a user opens a new section, the previously open section automatically
collapses. Simply add the shutters-autoclose CSS class to your
accordion container to enable this behavior.
Auto-close mode is ideal for FAQ sections, settings panels, mobile navigation menus, and any interface where showing one section at a time reduces cognitive load and keeps the layout compact.
Yes! Shutters supports multiple accordion instances on the same page. Each container is independently configured — you can have one accordion in auto-close mode and another allowing multiple panels open simultaneously.
How to Use Shutters Accordion
1. Installation
Install Shutters Accordion via npm, or include it directly from a CDN:
npm install shutters-accordion
Or include the CSS and JavaScript files directly in your HTML:
<link rel="stylesheet" href="shutters-core.css" />
<link rel="stylesheet" href="shutters-theme.css" />
<script type="module" src="shutters-core.js"></script>
2. HTML Structure
Create your accordion with clean, minimal HTML. ARIA attributes (role, tabindex, aria-expanded) are added automatically by JavaScript — you don't need to write them:
<div class="shutters-accordion">
<div class="shutters-item">
<div class="shutters-header">
<span class="shutters-title">Section Title</span>
<span class="shutters-icon"></span>
</div>
<div class="shutters-content">
<div class="shutters-body">
<p>Your content goes here</p>
</div>
</div>
</div>
</div>
3. Initialize JavaScript
Initialize the accordion with optional configuration options:
import ShuttersAccordion from 'shutters-accordion';
import 'shutters-accordion/style.css';
const accordion = new ShuttersAccordion({
container: '.shutters-accordion',
animationDuration: 300,
animationEasing: 'ease-in-out',
defaultOpen: 'none'
});
4. Configuration Options
5. Programmatic API
Control accordion items programmatically with the JavaScript API:
accordion.open(0); // Open item by index
accordion.close(2); // Close item by index
accordion.toggle(1); // Toggle item by index
accordion.openAll(); // Open all items
accordion.closeAll(); // Close all items
accordion.destroy(); // Remove all listeners and clean up
// Listen for state changes
accordion.on('shutters:open', (e) => {
console.log('Opened:', e.detail.item);
});
accordion.on('shutters:close', (e) => {
console.log('Closed:', e.detail.item);
});
6. Auto-Close Mode
Add the shutters-autoclose class to restrict the accordion to one open panel at a time:
<div class="shutters-accordion shutters-autoclose">
<!-- Only one item can be open at a time -->
</div>
7. Customization via CSS Custom Properties
Override CSS custom properties to match your design system:
.shutters-accordion {
--shutters-bg-color: #fff;
--shutters-border-color: #000;
--shutters-focus-color: #0066cc;
--shutters-hover-bg: #f5f5f5;
--shutters-text-color: #000;
--shutters-animation-duration: 0.5s;
--shutters-animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
Shutters vs Other Accordion Libraries
When choosing an accordion component for your website, key factors include bundle size, accessibility compliance, animation quality, and dependency requirements. Here's how Shutters compares to common alternatives:
jQuery UI's accordion requires jQuery as a dependency (~90KB minified), making it significantly heavier. Shutters has zero dependencies and weighs under 2KB gzipped. Shutters also uses modern CSS Grid animations instead of jQuery's JavaScript-driven height calculations, resulting in smoother 60fps transitions. For new projects, Shutters offers a modern, lightweight alternative.
The native <details>/<summary> elements provide
basic expand/collapse without JavaScript, but lack smooth animated transitions,
auto-close behavior, custom events, and programmatic control. Shutters adds smooth CSS Grid
animations, an auto-close mode, custom events (shutters:open/shutters:close),
a full programmatic API with on()/off() listeners, and consistent
cross-browser styling — while maintaining the same level of accessibility.
Framework-specific accordions (React Aria, Radix UI, Headless UI) are tightly coupled to their ecosystems. Shutters is framework-agnostic — it works with vanilla HTML, React, Vue, Svelte, Angular, Astro, or any other framework. If you need a single accordion component that works everywhere without lock-in, Shutters is the pragmatic choice.