Fylgja Accordion
An accordion is a set of stacked sections that each expand and collapse. Built on
the native <details> and <summary> elements, it is keyboard accessible and
toggleable without any JavaScript. Adding a shared name attribute turns the
group into an exclusive accordion where opening one section closes the rest.
Preview
What is Fylgja?
A lightweight, classless-friendly CSS library built on modern standards.
Does it require a build step?
No. Fylgja works buildless straight from a CDN, or with your bundler.
Is it accessible?
Yes. It builds on native elements, so semantics and keyboard support come for free.
<div class="divide-y" style="border-color: color-mix(in oklab, var(--root-bg) 75%, var(--root-fg))">
<details name="demo-accordion" class="flow-none" open>
<summary class="list-none flex align" style="--py: 0.75rem">
<span>What is Fylgja?</span>
<svg class="toggle-rotate transition flex-none" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</summary>
<p style="--py: 0 0.75rem">A lightweight, classless-friendly CSS library built on modern standards.</p>
</details>
<details name="demo-accordion" class="flow-none">
<summary class="list-none flex align" style="--py: 0.75rem">
<span>Does it require a build step?</span>
<svg class="toggle-rotate transition flex-none" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</summary>
<p style="--py: 0 0.75rem">No. Fylgja works buildless straight from a CDN, or with your bundler.</p>
</details>
<details name="demo-accordion" class="flow-none">
<summary class="list-none flex align" style="--py: 0.75rem">
<span>Is it accessible?</span>
<svg class="toggle-rotate transition flex-none" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
</summary>
<p style="--py: 0 0.75rem">Yes. It builds on native elements, so semantics and keyboard support come for free.</p>
</details>
</div>Usage
Each section is a <details> with a <summary> as its label, and its content
follows the summary. Give every <details> in the group the same name to make
it an exclusive accordion, or omit name to let multiple sections stay open at
once. Add open to the section that should start expanded.
Fylgja keeps the bare <details> deliberately plain, so the accordion look comes
entirely from Fylgja utilities, with no custom CSS:
divide-yon the wrapper draws a divider between each section. Give it a theme-aware color from Fylgja tokens, e.g.style="border-color: color-mix(in oklab, var(--root-bg) 75%, var(--root-fg))".flow-noneon each<details>clears the default margins from its summary and content so the padding stays even.list-noneon the summary hides the default disclosure triangle.flex alignon the summary pushes the label and chevron to opposite ends and centers them;flex-nonekeeps the chevron from shrinking.toggle-rotate transitionon the chevron flips it when the section opens.--pysets the vertical padding:style="--py: 0.75rem"on the summary andstyle="--py: 0 0.75rem"on the content.
Anatomy
| Part | Responsibility |
|---|---|
<details> |
One collapsible section. Tracks its own open state. |
<summary> |
The always-visible label and toggle. Focusable and keyboard-operable. |
name |
Shared across sections to enforce single-open (exclusive) behavior. |
.divide-y + .toggle-rotate |
Fylgja utilities that add the dividers and the rotating chevron. |
Accessibility
<summary>is focusable and toggles on Enter or Space by default.- Open state is exposed to assistive technology natively; no
aria-expandedwiring is required. - Keep the summary text meaningful on its own, since it acts as the section label.
FAQ
How do I make only one section open at a time?
Give every <details> in the group the same name attribute. The browser then treats them as an exclusive accordion and closes the others when one opens, with no JavaScript.
Do I need JavaScript for the open and close animation?
No. Modern browsers can animate the disclosure with CSS using interpolate-size and transitions on the details element, so the toggle stays entirely native.