Core · Show content
Accordion
Shows and hides sections of content with the native details and summary elements, one at a time if you name the group.
Example
A group of questions with their answers: opening one closes the one that was open.
What is a design token?
A named value, such as a color or a space, that components read instead of a literal.
Why only one open at a time?
The same name on each details connects them: opening one closes the other.
Does it need JavaScript?
No. The browser opens, closes and groups them.
Known issues
Two points to know before you rely on a named group.
Exclusive group. The name attribute works in Chrome and Edge 120, Safari 17.2 and Firefox 130, all from September 2024 or earlier, so it is not yet Baseline widely available. In an older browser each panel opens on its own: nothing is lost.
Screen readers. How NVDA, JAWS, VoiceOver, TalkBack and Orca announce an exclusive group has not been tested for LUZ, and no support data was checked. The grouping of an exclusive set is not described to assistive technology: the HTML accessibility mapping for it is still an open issue (see the Open UI explainer).
Code
Copy the markup
A bare details needs no class: a summary and a divider, with no box.
<details>
<summary>What is a design token?</summary>
<p>A named value that components read.</p>
</details>
.luz-accordion adds the box and the group. With the class:
<div class="luz-accordion">
<details name="faq" open>
<summary>What is a design token?</summary>
<p>A named value that components read.</p>
</details>
<details name="faq">
<summary>Does it need JavaScript?</summary>
<p>No.</p>
</details>
</div>
Variants and options
A single <details> needs no class: the elements layer styles it. The class only joins a stack.
| Class or attribute | What it does |
|---|---|
.luz-accordion | Joins the <details> inside it into one block: one edge between them, rounded corners only on the block |
name="…" | Connects the details with the same name: only one is open at a time. They need not be adjacent |
open | Starts a panel open. In a named group, only the first open one in the source stays open |
How it works
Native <details> and <summary>, styled by elements/interactive.css with no class. components/accordion.css adds only the joined block.
No JavaScript.
- The summary is the label of the panel; the rest of the details is its content.
- Closed content is not shown and is out of the reading order until the panel opens.
Without JavaScript
Nothing changes: opening, closing and grouping are the browser's. The accordion is complete without a script.
Keyboard and ARIA
Tab reaches each summary in order. Enter or Space opens or closes it.
There are no arrow-key shortcuts between panels.
- Add no role: a
<details>already has its semantics, and no ARIA role is allowed on it. - Keep links and buttons out of the summary: it is itself the control.
Contrast and focus are in the Design tab.
Design
When to use
Use an accordion for content that most readers can skip, grouped under short titles.
- Frequently asked questions and long reference lists.
- Optional detail under a short answer.
When not to use
Do not hide what every reader needs, and do not use it to move around the site.
- For the main sections of a site, use a sidebar. For content a reader switches between, use tabs.
- Do not put an error, a warning or a required step inside a closed panel.
- With only one or two short answers, show them as plain text.
Do and don't
Writing the content
- Write the summary as the question or the topic, in sentence case, in a few words.
- Put the answer first in the panel. Keep it short; link to a page for more.
- Order the panels as readers ask: most common first.
Contrast and focus
The text and the marker use the primary text color on the surface.
| Part | Colour on background | Light | Dark | High contrast | Needs |
|---|---|---|---|---|---|
Summary text | --luz-text-primary on --luz-surface | 16.5:1 | 14.0:1 | 21.0:1 | 4.5:1 |
Summary under the pointer | --luz-text-primary on --luz-surface-hover | 14.4:1 | 12.6:1 | 20.1:1 | 4.5:1 |
Focus ring | --luz-focus-ring on --luz-surface | 5.9:1 | 7.2:1 | 21.0:1 | 3:1 |
Measured from the token values of each mode, rounded down. Needs is the WCAG 2.2 AA minimum: 4.5:1 for text, 3:1 for focus rings, borders and icons.
- Focus: the summary has the shared 2 px
--luz-focus-ringoutline, 2 px outside the box. - Not colour alone: open and closed are told apart by the marker, which turns, and not by the border or the background.
Tokens it uses
The 6 tokens that components/accordion.css reads, by family. Each family links to its page, with the values in every mode. In Figma they are variables with the same names: see Tokens in Figma.
- Spacing and sizing
--luz-space-sm,--luz-space-xs- Radius
--luz-radius-md- Motion
--luz-duration-base
The look of one details and its summary, with its own tokens, comes from elements/interactive.css.
Keyboard and ARIA are in the Code tab.