Skip to main content

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?

Zero Dependencies & Tiny Footprint

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.

Built-In Accessibility (WCAG 2.1 Compliant)

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.

Smooth 60fps CSS Grid Animations

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.

Simple API & Easy Integration

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

What is the Shutters Accordion?

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.

How does the CSS Grid animation technique work?

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
What are the key features?

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:open and shutters:close via 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.

What is auto-close mode?

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.

When should I use auto-close?

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.

Can I mix auto-close and multi-open accordions?

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

container
CSS selector, DOM element, or array of containers (default: '.shutters-accordion')
animationDuration
Animation speed in milliseconds (default: 300)
animationEasing
CSS easing function (default: 'ease-in-out')
defaultOpen
Default open items: 'first', 'all', 'none', or an index array like [0, 2]

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:

Shutters vs jQuery UI Accordion

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.

Shutters vs HTML <details>/<summary>

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.

Shutters vs Framework-Specific Accordions

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.