npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shutters-accordion

v1.1.1

Published

Shutters — a lightweight, accessible, dependency-free JavaScript accordion component with smooth CSS Grid animations, ARIA support, keyboard navigation, auto-close mode, and full customization via CSS custom properties. Under 2KB gzipped.

Readme

Shutters Accordion

A lightweight, accessible, dependency-free JavaScript accordion component with smooth CSS Grid animations.

npm version License: MIT Bundle Size Zero Dependencies Accessibility

Live Demo · GitHub Repository · Report a Bug


Why Shutters?

Shutters is the accordion component you reach for when you want something that just works — lightweight, accessible, and smooth — without pulling in a framework or a heavy UI library.

| Feature | Shutters | jQuery UI Accordion | Native <details> | Framework-Specific | |---|---|---|---|---| | Bundle Size | < 2KB gzip | ~90KB (jQuery required) | 0KB (native) | Varies (framework required) | | Dependencies | Zero | jQuery | None | Framework runtime | | Smooth Animations | CSS Grid 60fps | JS-driven height calc | No animation | Varies | | Auto-Close Mode | Built-in | Built-in | Not available | Varies | | Keyboard Accessible | Full (Enter/Space/Arrow/Home/End) | Full | Partial | Varies | | ARIA Support | Automatic (auto-applied by JS) | Manual | Partial | Varies | | Programmatic API | open/close/toggle/openAll/closeAll/on/off/destroy | Full API | None | Varies | | Custom Events | shutters:open / shutters:close | Yes | toggle event | Varies | | Framework Agnostic | Yes | Yes (needs jQuery) | Yes | No | | CSS Custom Properties | Full theming | Limited | N/A | Varies |

Key Advantages

  • Under 2KB gzipped — one of the smallest accordion solutions available
  • Zero dependencies — no jQuery, no framework, pure vanilla JavaScript + CSS
  • 60fps CSS Grid animations — uses grid-template-rows transitions instead of janky max-height hacks
  • Fully accessible — automatic ARIA setup, full keyboard navigation (Arrow/Home/End), visible focus indicators
  • Auto-close mode — optional single-panel-open behavior with one CSS class
  • Custom events — subscribe to shutters:open and shutters:close via on()/off()
  • Event delegation — one listener per container for optimal performance at any scale
  • Framework agnostic — works with vanilla HTML, React, Vue, Svelte, Angular, Astro, or any framework
  • Customizable — theme everything via CSS custom properties
  • Programmatic controlopen(), close(), toggle(), openAll(), closeAll(), destroy() API methods
  • ES Module + UMD — works with Vite, Webpack, Rollup, or a <script> tag
  • Modular CSS — separate core functionality from optional presentation theme

Installation

npm

npm install shutters-accordion

GitHub Packages

# Configure .npmrc first (see docs/GITHUB_PACKAGES.md)
npm install @byronjohnson/shutters-accordion

CDN

<!-- ES Module (CSS must be linked separately) -->
<script type="module">
  import ShuttersAccordion from 'https://unpkg.com/[email protected]/dist/shutters.es.js';
</script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/style.css">

<!-- UMD (CSS is auto-injected by the script) -->
<script src="https://unpkg.com/[email protected]/dist/shutters.umd.js"></script>

Direct Download

Download shutters-core.js and shutters-core.css from the src/ directory and include them in your project.


Quick Start

1. Add the HTML Structure

<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>

Note: ARIA attributes (role="button", tabindex="0", aria-expanded) are added automatically by JavaScript at initialization — you don't need to write them in your HTML.

2. Include the CSS

<!-- Core CSS (required) -->
<link rel="stylesheet" href="shutters-core.css">

<!-- Theme CSS (optional — provides default black-and-white styling) -->
<link rel="stylesheet" href="shutters-theme.css">

3. Initialize with JavaScript

ES Module

import ShuttersAccordion from 'shutters-accordion';
import 'shutters-accordion/style.css';

const accordion = new ShuttersAccordion({
  container: '.shutters-accordion',
  animationDuration: 300,
  animationEasing: 'ease-in-out',
  defaultOpen: 'first'
});

UMD (Browser Global)

<!-- UMD script auto-injects CSS — no separate stylesheet needed -->
<script src="path/to/shutters.umd.js"></script>

<script>
  const accordion = new ShuttersAccordion({
    container: '.shutters-accordion'
  });
</script>

Configuration Options

| Option | Type | Default | Description | |---|---|---|---| | container | string \| Element \| NodeList \| Array | '.shutters-accordion' | CSS selector, DOM element, or array of container elements | | animationDuration | number | 300 | Animation speed in milliseconds | | animationEasing | string | 'ease-in-out' | CSS easing function for transitions | | defaultOpen | string \| Array | 'none' | Which items to open initially: 'first', 'all', 'none', or an index array like [0, 2] |


API Methods

const accordion = new ShuttersAccordion({
  container: '.shutters-accordion'
});

// Open an accordion item by its zero-based index
accordion.open(0);

// Close an accordion item by index
accordion.close(0);

// Toggle an accordion item by index
accordion.toggle(0);

// Open or close all items at once
accordion.openAll();
accordion.closeAll();

// 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);
});

// Remove a specific listener
accordion.off('shutters:close', myCallback);

// Destroy the instance and remove all event listeners
accordion.destroy();

Auto-Close Mode

Add the shutters-autoclose class to your accordion container to ensure only one panel is open at a time:

<div class="shutters-accordion shutters-autoclose">
  <div class="shutters-item">
    <!-- Only one item can be open at a time -->
  </div>
</div>

This is perfect for FAQ sections, settings panels, and mobile navigation menus.


Customization

Shutters separates core functionality CSS from presentation theme CSS. The core CSS handles the expand/collapse mechanics, while the theme CSS provides visual styling.

CSS Custom Properties

Override these 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.3s;
  --shutters-animation-easing: ease-in-out;
}

Dark Mode Example

.shutters-accordion.dark-theme {
  --shutters-bg-color: #1a1a2e;
  --shutters-border-color: #333;
  --shutters-focus-color: #4da6ff;
  --shutters-hover-bg: #16213e;
  --shutters-text-color: #e0e0e0;
}

How the CSS Grid Animation Works

Shutters uses the modern CSS Grid grid-template-rows transition technique — the same approach recommended by Google's web.dev team for animating content height. Instead of:

  • max-height hacks (janky, requires guessing a large value)
  • ❌ JavaScript-measured scrollHeight animations (causes layout thrashing)
  • transform: scaleY() (distorts content)

Shutters does:

  • ✅ Transitions grid-template-rows from 0fr to 1fr
  • ✅ GPU-accelerated, 60fps smooth animations
  • ✅ Works with any dynamic content height
  • ✅ No layout thrashing or reflows
/* Collapsed state */
.shutters-content {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s ease-in-out;
}

/* Expanded state */
.opened .shutters-content {
  grid-template-rows: 1fr;
}

Accessibility

Shutters implements the WAI-ARIA Accordion Pattern with:

  • Automatic ARIA setuprole="button", tabindex="0", and aria-expanded are applied by JS at initialization
  • aria-expanded="true|false" kept in sync with open/closed state
  • Enter and Space key activation
  • Arrow Up/Down to move focus between headers
  • Home/End to jump to the first/last header
  • Visible :focus-visible indicators for keyboard users
  • Compatible with screen readers (NVDA, JAWS, VoiceOver)

Browser Support

| Browser | Version | |---|---| | Chrome | 57+ | | Firefox | 52+ | | Safari | 10.1+ | | Edge | 16+ | | iOS Safari | 10.3+ | | Chrome Android | 57+ |

Requires CSS Grid support (grid-template-rows transitions).


Use Cases

Shutters Accordion is ideal for:

  • FAQ sections — organize frequently asked questions with auto-close mode
  • Product feature lists — expandable feature descriptions on landing pages
  • Settings panels — collapsible configuration groups in dashboards
  • Documentation — organize API references and guides into expandable sections
  • Mobile navigation — compact, accessible navigation menus
  • Pricing tables — expandable plan details and feature comparisons
  • Content-heavy pages — reduce visual clutter while keeping all content accessible

Development

# Start development server
npm run dev

# Start demo development server
npm run dev:demo

# Build library for production
npm run build

# Build demo for deployment
npm run build:demo

# Build both library and demo
npm run build:all

# Preview production build
npm run preview

Versioning

Current version: 1.1.0

The version is managed in package.json and the VERSION file. Use npm version to bump versions.


Publishing

# Update version in package.json, VERSION file, and CHANGELOG.md
npm version patch  # or minor, major

# Build the package
npm run build

# Publish to npm
npm publish

Frequently Asked Questions

Is Shutters Accordion free to use?

Yes. Shutters is open-source software released under the MIT License. You can use it in personal and commercial projects without restriction.

Does Shutters work with React / Vue / Svelte / Angular?

Yes. Shutters is framework-agnostic. It works with any framework or plain HTML because it operates on standard DOM elements. Simply render the expected HTML structure and initialize Shutters in your component's mount lifecycle.

How small is Shutters compared to other accordion libraries?

Shutters weighs under 2KB gzipped (JS + CSS combined). By comparison, jQuery UI Accordion requires jQuery (~90KB), and most framework-specific accordion components add to your existing framework bundle.

Can I have multiple accordions on the same page?

Yes. Pass a CSS selector that matches multiple containers, or pass an array of DOM elements. Each container operates independently — you can mix auto-close and multi-open accordions on the same page.

Does Shutters support nested accordions?

Shutters works with nested accordion structures. Each level should use its own ShuttersAccordion instance targeting the appropriate container.

How do I animate the accordion icon?

Shutters includes a default + icon that rotates 45° (becoming ×) when expanded. This is handled by the .shutters-icon::before CSS. You can override this with your own icon by modifying the CSS or replacing the icon element.


License

MIT © Byron Johnson

See LICENSE for details.