Basic Accordion (without animation)

Only one section can be open at a time. Without animation - content shows/hides instantly.

Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them.

Specifically, it means that people can perceive, understand, navigate, and interact with the web.

The web is an increasingly important resource in many aspects of life: education, employment, government, commerce, health care, recreation, and more.

It is essential that the web be accessible to provide equal access and opportunity to people with diverse abilities.

Web accessibility benefits people with disabilities, but also:

  • Older people with changing abilities due to aging
  • People with temporary disabilities (broken arm, lost glasses)
  • People in limited situations (bright sunlight, can't listen to audio)
  • People with slow internet connections

Accordion (CSS Grid animations by default)

Accordion has CSS Grid animations by default (grid-template-rows: 0fr → 1fr). To disable animations, use the data-no-animation attribute.

Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them.

Specifically, it means that people can perceive, understand, navigate, and interact with the web.

The web is an increasingly important resource in many aspects of life: education, employment, government, commerce, health care, recreation, and more.

It is essential that the web be accessible to provide equal access and opportunity to people with diverse abilities.

Web accessibility benefits people with disabilities, but also:

  • Older people with changing abilities due to aging
  • People with temporary disabilities (broken arm, lost glasses)
  • People in limited situations (bright sunlight, can't listen to audio)
  • People with slow internet connections

Custom Animation Speed

Animation speed can be set using CSS custom properties (variables). You can set them globally in CSS or inline using the style attribute.

Slow animation (0.6s)

This section opens and closes slower (0.6s instead of default 0.3s).

Fast animation (0.15s)

This section opens and closes faster (0.15s instead of default 0.3s).

Custom easing

This section uses a custom easing function for a "bounce" effect.

Multiple Expand Accordion

Multiple sections can be open simultaneously.

ARIA (Accessible Rich Internet Applications) is a set of attributes that define ways to make web content and web applications more accessible to people with disabilities.

All functionality must be available from a keyboard. Users with motor disabilities often use a keyboard instead of a mouse.

Focus should always be visible and should follow a logical navigation order. Focus trap is used in modal dialogs and offcanvas panels.

With Toggle All Control

Accordion with a single toggle button that toggles all sections at once. The button changes text and icon based on state (open/closed).

HTML (HyperText Markup Language) is the standard markup language for creating web pages.

CSS (Cascading Style Sheets) is the language used to describe the presentation of a document written in HTML.

JavaScript is a programming language that enables you to implement complex features on web pages.

Standalone Collapse Toggle (without animation)

Standalone button that toggles visibility of panel(s) via CSS selector.

Detailed Information

This is a panel that can be shown or hidden using a standalone toggle button.

This pattern is useful for simple show/hide functionality outside of accordion groups.

Standalone Collapse (animations by default)

Standalone panel has CSS Grid animation by default. To disable animations, use the data-no-animation attribute.

Animated Detailed Information

This panel uses CSS Grid for smooth animation when opening/closing.

Animation works without needing to know the content height in advance.

Toggle Multiple Panels at Once

One button can control multiple panels simultaneously using a class selector.

Info Panel 1: First information panel
Info Panel 2: Second information panel
Info Panel 3: Third information panel

Style Variants

Bordered Variant

Accordion without borders, only separators between items.

Content of the first item in bordered variant.

Content of the second item in bordered variant.

Content of the third item in bordered variant.

Separated Variant

Accordion with more spacing and shadow between items.

Content of the first item in separated variant.

Content of the second item in separated variant.

Compact Variant

Smaller padding and font size for a more compact look.

Content in compact style.

More content in compact style.

Large Variant

Larger padding and font size for a more prominent look.

Content in large style with more padding.

More content in large style.

Usage

Basic Accordion (Single Expand):

<div data-accordion>
    <div data-accordion-item>
        <button data-accordion-trigger>
            Section 1
        </button>
        <div data-accordion-panel>
            <div>
                Section 1 content
            </div>
        </div>
    </div>

    <div data-accordion-item>
        <button data-accordion-trigger>
            Section 2
        </button>
        <div data-accordion-panel>
            <div>
                Section 2 content
            </div>
        </div>
    </div>
</div>

Animations (by default):

<!-- Animations are default, no need to add any attribute -->
<div data-accordion>
    <div data-accordion-item>
        <button data-accordion-trigger>Section 1</button>
        <div data-accordion-panel>
            <!-- Wrapper div is REQUIRED for proper animation -->
            <div>
                <div>
                    Section 1 content
                </div>
            </div>
        </div>
    </div>
</div>

Important for animation:
• Animations are default - automatically enabled
• Required structure: panel > wrapper (overflow) > content (padding)
• First div: technical wrapper with overflow: hidden (NO padding)
• Second div: content container (has padding)
• Animation: CSS Grid (grid-template-rows: 0fr → 1fr)
• Works without knowing content height in advance
• Speed: --a11y-accordion-duration (default: 0.3s)
• Easing: --a11y-accordion-easing (default: ease)
• Automatic support for prefers-reduced-motion

Setting Animation Speed:

<!-- Inline using style attribute -->
<div data-accordion style="--a11y-accordion-duration: 0.6s;">
    <!-- accordion items -->
</div>

<!-- Custom easing -->
<div data-accordion
     style="--a11y-accordion-duration: 0.4s; --a11y-accordion-easing: cubic-bezier(0.68, -0.55, 0.265, 1.55);">
    <!-- accordion items -->
</div>

<!-- Or globally in CSS -->
<style>
:root {
    --a11y-accordion-duration: 0.5s;
    --a11y-accordion-easing: ease-in-out;
}
</style>

<!-- Disable animations -->
<div data-accordion data-no-animation>
    <!-- accordion without animations -->
</div>

Multiple Expand Accordion:

<div data-accordion data-accordion-multiple>
    <!-- accordion items -->
</div>

With Toggle All Control:

<div data-accordion data-accordion-multiple>
    <!-- Toggle control at top (created automatically) -->
    <div data-accordion-controls="top"></div>

    <!-- Accordion items -->

    <!-- Toggle control at bottom (created automatically) -->
    <div data-accordion-controls="bottom"></div>
</div>

Toggle button behavior:
• Created automatically with dynamic texts "Expand All" / "Collapse All"
• Text in <span> changes: "Expand All" / "Collapse All"
• Aria-label changes: "Expand all panels" / "Collapse all panels"
• Toggle icon (plus/minus) changes based on state
• Aria-expanded attribute reflects current state (true/false)
• Aria-controls contains IDs of all panels
• If multiple toggle buttons exist (top and bottom), all are synchronized on click

Custom Toggle All Button:

<div data-accordion data-accordion-multiple>
    <div data-accordion-controls="top">
        <button
            data-accordion-toggle-all
            data-text-for-show="Expand All"
            data-text-for-hide="Collapse All"
            data-aria-label-for-show="Expand all sections"
            data-aria-label-for-hide="Collapse all sections">
            <svg aria-hidden="true" width="16" height="16">
              <path class="toggle-icon-expand" d="M8 3v10M3 8h10"/>
              <path class="toggle-icon-collapse" d="M3 8h10" style="display: none;"/>
            </svg>
            <span>Expand All</span>
        </button>
    </div>
    <!-- accordion items -->
</div>

Important:
• Button must contain a <span> element for dynamic text
• Icons use classes .toggle-icon-expand and .toggle-icon-collapse
• Attribute data-accordion-toggle-all is required
• data-aria-label-for-show/hide are optional (if not set, text from data-text-for-show/hide is used)

Standalone Toggle (without animation):

<!-- With ID selector -->
<button data-collapse-toggle="#panel-1">
    Open Panel
</button>

<div id="panel-1" data-no-animation>
    <div>
        Panel content...
    </div>
</div>

<!-- With class selector (controls multiple panels) -->
<button data-collapse-toggle=".info-panel">
    Toggle All Info Panels
</button>

<div class="info-panel" data-no-animation><div><div>Panel 1</div></div></div>
<div class="info-panel" data-no-animation><div><div>Panel 2</div></div></div>

Standalone Toggle (animations by default):

<!-- Animations are default, no need to add any attribute -->
<button data-collapse-toggle="#panel">
    Open Panel
</button>

<div id="panel">
    <!-- First div: overflow wrapper (overflow: hidden, grid-row: 1/span 2) -->
    <div>
        <!-- Second div: content wrapper (padding) -->
        <div>
            Panel content...
        </div>
    </div>
</div>

<!-- Disable animations -->
<div id="no-animation-panel" data-no-animation>
    <div>
        <div>
            Panel without animation
        </div>
    </div>
</div>

Standalone Toggle with Dynamic Texts:

<!-- Same text for aria-label and visible text -->
<button
    data-collapse-toggle="#detail-panel"
    data-text-for-show="Show Details"
    data-text-for-hide="Hide Details">
    <span>Show Details</span>
</button>

<!-- Different texts for aria-label and visible text -->
<button
    data-collapse-toggle=".info-panel"
    data-text-for-show="Show All"
    data-text-for-hide="Hide All"
    data-aria-label-for-show="Show all info panels"
    data-aria-label-for-hide="Hide all info panels">
    <span>Show All</span>
</button>

Behavior:
• Button must contain a <span> element for dynamic text
• Text in <span> changes based on data-text-for-show/hide
• Aria-label changes based on data-aria-label-for-show/hide (if set)
• If data-aria-label-* are not set, text from data-text-for-show/hide is used for aria-label as well
• aria-expanded is automatically set to true/false

JavaScript Initialization:

1. ES6 Module Import - init functions (Recommended)

import { initAccordions, initCollapses } from './a11y-kit/a11y-accordion.js';

// Initialize after DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  initAccordions(); // Everything (collapse + accordion groups)
  // OR
  initCollapses();  // Only standalone collapse toggles
});

2. ES6 Module Import - Bootstrap Style

import { Collapse, Accordion } from './a11y-kit/a11y-accordion.js';

// Only standalone collapse toggles
const collapse = new Collapse();

// Everything (collapse + accordion groups)
const accordion = new Accordion();

3. NPM package (Module bundlers: Astro, Vite, Webpack)

npm install accessible-kit

// Import only what you need (best for tree-shaking)
import { initCollapses, initAccordions, Collapse, Accordion } from 'accessible-kit/accordion';

// Initialize after DOM is ready
document.addEventListener('DOMContentLoaded', () => {
  initAccordions(); // Auto-init all accordions

  // OR create instances manually
  const accordion = new Accordion();
});

Keyboard Navigation (in accordion groups)

  • - Move to next trigger
  • - Move to previous trigger
  • Home - Move to first trigger
  • End - Move to last trigger
  • Enter / Space - Toggle accordion item

Features