Accordion

Accordion creates expandable content sections with smooth open and close animations. The visual structure is driven by CSS — the FrontAlign runtime handles interaction, state, animation, and lifecycle events automatically through delegated event handling.

Accordion is suited for FAQ sections, settings panels, documentation navigation, product detail pages, sidebar menus, and any interface that benefits from progressive disclosure.


Getting Started

Add fa-component="accordion" to the root element so the FrontAlign runtime can activate delegated behavior. No manual event listeners are needed.

  <div className="accordion" fa-component="accordion">
    <div className="accordion-item">
      <button className="button accordion-toggler">What is FrontAlign</button>
      <div className="accordion-content">
        <div className="accordion-inner">
          FrontAlign combines a design-token CSS foundation with an intelligent JavaScript runtime.
        </div>
      </div>
    </div>

    <div className="accordion-item">
      <button className="button accordion-toggler">Can I use it with React?</button>
      <div className="accordion-content">
        <div className="accordion-inner">
          Yes. FrontAlign provides a React integration layer for hooks, providers, and runtime helpers.
        </div>
      </div>
    </div>
  </div>

Runtime

The Javascript runtime is required for the Accordion component to function correctly. To do this, a new FrontAlign instance must be created on the page. React users, however, simply need to use the useAccordion hook.

'use client';

import { useAccordion } from 'frontalign/react';

export function AccordionExample() {
  useAccordion();

  return (
    <div className="accordion">
      <div className="accordion-item is-active">
        <button className="accordion-header">What is FrontAlign?</button>
        <div className="accordion-body">
          <p>FrontAlign is a UI component library with React integration out of the box.</p>
        </div>
      </div>
      <div className="accordion-item">
        <button className="accordion-header">How do I install it?</button>
        <div className="accordion-body">
          <p>Run <code>npm install frontalign</code> and import the CSS and hooks.</p>
        </div>
      </div>
    </div>
  );
}

After new FrontAlign() runs on the client, delegated accordion behavior is activated. You do not need to manually attach event listeners to each item.

FrontAlign combines a design-token CSS foundation with an intelligent JavaScript runtime.

Yes. FrontAlign provides a React integration layer for hooks, providers, and runtime helpers.

Structure

The accordion markup is intentionally simple.

ElementClass / attributePurpose
RootaccordionGroups accordion items.
Runtime markerfa-component="accordion"Marks the component for FrontAlign runtime behavior.
Itemaccordion-itemWraps one toggle and one content panel.
Triggeraccordion-togglerClickable element that opens or closes the panel.
Panelaccordion-contentCollapsible content region.
Inner wrapperaccordion-innerProvides consistent content padding.

Basic Example

<div class="accordion" fa-component="accordion">
  <div class="accordion-item">
    <button class="accordion-toggler">
      Installation
    </button>

    <div class="accordion-content">
      <div class="accordion-inner">
        Install FrontAlign from NPM or use the CDN build.
      </div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="accordion-toggler">
      Runtime
    </button>

    <div class="accordion-content">
      <div class="accordion-inner">
        The runtime initializes delegated component behavior on the client.
      </div>
    </div>
  </div>
</div>

Configuration Attributes

Accordion supports runtime attributes on the root element.

AttributeDefaultBehavior
data-single-opentrueOnly one panel stays open at a time. Set to false to allow multiple panels open.
data-open-stayfalseWhen set to true, the first accordion item is opened on initialization.

Single Open Mode

By default, Accordion keeps only one item open at a time.

When a new panel opens, the runtime closes other opened panels in the same accordion root.

<div class="accordion" fa-component="accordion">
  <div class="accordion-item">
    <button class="accordion-toggler">First</button>
    <div class="accordion-content">
      <div class="accordion-inner">First panel</div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="accordion-toggler">Second</button>
    <div class="accordion-content">
      <div class="accordion-inner">Second panel</div>
    </div>
  </div>
</div>

This is the default behavior because data-single-open is treated as true unless explicitly set to false.

Multiple Open Panels

Set data-single-open="false" when multiple panels should be allowed to stay open.

<div class="accordion" fa-component="accordion" data-single-open="false">
  <div class="accordion-item">
    <button class="button accordion-toggler">Account</button>
    <div class="accordion-content">
      <div class="accordion-inner">Account settings.</div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="button accordion-toggler">Notifications</button>
    <div class="accordion-content">
      <div class="accordion-inner">Notification settings.</div>
    </div>
  </div>
</div>
Account settings.
Notification settings.

Open First Item on Load

Set data-open-stay="true" when the first accordion item should be open after initialization.

<div class="accordion" fa-component="accordion" data-open-stay="false">
  <div class="accordion-item">
    <button class="button accordion-toggler">Account</button>
    <div class="accordion-content">
      <div class="accordion-inner">Account settings.</div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="button accordion-toggler">Notifications</button>
    <div class="accordion-content">
      <div class="accordion-inner">Notification settings.</div>
    </div>
  </div>
</div>

The runtime adds the opened class to the first toggler and sets the first content panel to display: block.

Account settings.
Notification settings.

Size Variants

Accordion supports size variants on the root element.

ClassEffectBest for
accordionDefault compact spacing.General content and sidebars.
is-mediumIncreases item and inner spacing.Documentation pages and settings panels.
is-largeProvides the most spacious layout.Marketing sections and FAQ blocks.
<div class="accordion is-medium" fa-component="accordion" data-open-stay="false">
  <div class="accordion-item">
    <button class="button accordion-toggler">Account</button>
    <div class="accordion-content">
      <div class="accordion-inner">Account settings.</div>
    </div>
  </div>

  <div class="accordion-item">
    <button class="button accordion-toggler">Notifications</button>
    <div class="accordion-content">
      <div class="accordion-inner">Notification settings.</div>
    </div>
  </div>
</div>

Account settings.
Notification settings.

Open State

The runtime uses the opened class on the toggler to rotate the indicator icon.

StateClassBehavior
ClosedNo opened classThe content panel remains hidden.
OpenopenedThe indicator rotates and the content panel becomes visible.
.accordion-toggler.opened::after {
  transform: rotate(180deg);
}

The content panel starts with display: none. The runtime opens and closes it with slide animations.

Icon Indicator

Accordion togglers include a built-in arrow indicator through CSS.

The icon is created with a masked SVG and uses currentColor, so it automatically follows the text color of the toggler.

.accordion-toggler::after {
  margin-inline-start: auto;
  background-color: currentColor;
  transition: transform 0.15s ease-out, opacity 0.15s ease-out;
}

This keeps the indicator theme-aware without requiring extra markup.

FAQ Pattern

<section>
  <h2>Frequently Asked Questions</h2>

  <div class="accordion is-medium" fa-component="accordion" data-open-stay="true">
    <div class="accordion-item">
      <button class="button accordion-toggler">
        Does FrontAlign require a build step?
      </button>

      <div class="accordion-content">
        <div class="accordion-inner">
          No. You can use FrontAlign through CDN or NPM depending on your workflow.
        </div>
      </div>
    </div>

    <div class="accordion-item">
      <button class="button accordion-toggler">
        Can I use it with React?
      </button>

      <div class="accordion-content">
        <div class="accordion-inner">
          Yes. Use the React integration layer for provider setup, hooks, and runtime helpers.
        </div>
      </div>
    </div>
  </div>
</section>

Frequently Asked Questions

No. You can use FrontAlign through CDN or NPM depending on your workflow.

Yes. Use the React integration layer for provider setup, hooks, and runtime helpers.

Runtime Behavior

Accordion is initialized through the FrontAlign runtime.

When new FrontAlign() runs, the delegated component system listens for clicks on .accordion-toggler, finds the closest [fa-component="accordion"] root, and updates the related .accordion-content.

BehaviorDescription
Delegated eventsAccordion triggers do not need individual listeners.
LockingThe root uses an internal lock while animations are running.
Single-open modeBy default, opening one panel closes other open panels in the same root.
Multiple-open modedata-single-open="false" allows multiple panels to remain open.
Default open modedata-open-stay="true" opens the first item when initialized.
Slide animationThe runtime uses slide up and slide down helpers for open and close transitions.

Lifecycle Events

Accordion dispatches lifecycle events before and after opening or closing.

The open and close events are cancelable. Call event.preventDefault() to stop the action.

EventCancelableWhen it fires
fa.accordion.openYesBefore a panel opens.
fa.accordion.openedNoAfter a panel opens.
fa.accordion.closeYesBefore a panel closes.
fa.accordion.closedNoAfter a panel closes.

Each event includes trigger, content, and item in event.detail.

document.addEventListener('fa.accordion.opened', (event) => {
  const { trigger, content, item } = event.detail;

  console.log('Accordion opened:', trigger, content, item);
});

Prevent Opening

Use the cancelable fa.accordion.open event when an accordion panel should not open under certain conditions.

document.addEventListener('fa.accordion.open', (event) => {
  const { trigger } = event.detail;

  if (trigger.dataset.locked === 'true') {
    event.preventDefault();
  }
});

React Usage

For React and Next.js projects, use the React integration layer instead of manually wiring accordion behavior inside every component.

import { useAccordion } from 'frontalign/react';

export function FAQAccordion() {
  useAccordion();

  return (
    <div className="accordion is-medium" fa-component="accordion" data-open-stay="true">
      <div className="accordion-item">
        <button className="button accordion-toggler">
          Does FrontAlign work with React?
        </button>

        <div className="accordion-content">
          <div className="accordion-inner">
            Yes. The React integration layer connects FrontAlign behavior to React apps.
          </div>
        </div>
      </div>
    </div>
  );
}

Continue with the React Integration guide for provider setup, hooks, runtime helpers, and Next.js usage.

Accessibility

Use semantic buttons for accordion toggles.

Recommended practices:

  • Use <button> for .accordion-toggler.
  • Keep the button text descriptive.
  • Do not put important content only inside collapsed panels.
  • Keep the DOM order logical.
  • Avoid using accordion behavior for critical navigation unless the collapsed state remains understandable.

If your application requires strict WAI-ARIA accordion semantics, you may add aria-expanded, aria-controls, and matching panel IDs in your markup.

<button
  class="accordion-toggler"
  aria-expanded="false"
  aria-controls="faq-panel-1">
  What is FrontAlign?
</button>

<div id="faclass="accordion-content">
  <div class="accordion-inner">
    FrontAlign is a modern UI engine.
  </div>
</div>

Class Reference

ClassRole
accordionRoot accordion wrapper.
accordion-itemSingle accordion section.
accordion-togglerClickable trigger element.
accordion-contentCollapsible panel.
accordion-innerInner content wrapper with padding.
openedActive state class applied to the toggler.
is-mediumMedium accordion spacing variant.
is-largeLarge accordion spacing variant.

Notes

  • Accordion requires the FrontAlign runtime for interaction.
  • Initialize the runtime once with new FrontAlign().
  • The root must include fa-component="accordion".
  • The CSS controls structure, spacing, colors, and the indicator icon.
  • The runtime controls opening, closing, animation, events, and state classes.
  • data-single-open="false" allows multiple panels to remain open.
  • data-open-stay="true" opens the first item during initialization.
  • Use the React hook only in React or Next.js applications.
  • Use the React Integration guide when building with React.

FrontAlign