Accordion
An accordion is a stack of sections. Each section has a header that shows or hides its content.
Standard shipping arrives in 3 to 5 business days.
Return any unworn item within 30 days for a full refund.
<tk-accordion>
<tk-accordion-item open>
<span slot="header">Shipping</span>
<p>Standard shipping arrives in 3 to 5 business days.</p>
</tk-accordion-item>
<tk-accordion-item>
<span slot="header">Returns</span>
<p>Return any unworn item within 30 days for a full refund.</p>
</tk-accordion-item>
</tk-accordion>Anatomy
| Part | What it is |
|---|---|
tk-accordion |
the stack; adds no Tab stop |
tk-accordion-item |
one section |
header slot |
the section title |
| default slot | the content, shown when the section is open |
header part |
the heading around the trigger |
trigger part |
the header button, with a chevron on the right; one Tab stop |
panel part |
the content region |
The open section works as one card: a click anywhere on its content closes it. Links, buttons, form controls, and selected text inside keep working as usual.
Single or multiple open
By default, several sections can be open at once. Add single to keep only one open:
opening a section closes the others. Closing the open one is always allowed.
Yes, at any time.
Yes, from Billing.
<tk-accordion single> <tk-accordion-item open><span slot="header">Can I change my plan?</span><p>Yes, at any time.</p></tk-accordion-item> <tk-accordion-item><span slot="header">Can I cancel?</span><p>Yes, from Billing.</p></tk-accordion-item> </tk-accordion>
Don't use single when people need to compare two sections.
States
Name, photo, and bio.
Roles and invites.
<tk-accordion> <tk-accordion-item open><span slot="header">Profile</span><p>Name, photo, and bio.</p></tk-accordion-item> <tk-accordion-item disabled><span slot="header">Team settings</span><p>Roles and invites.</p></tk-accordion-item> </tk-accordion>
Hover and press shade the header row, or the whole card when the section is open. Keyboard focus shows a ring inside the header row.
open: the section starts open. The accordion toggles it from then on; read or set theopenproperty from code.disabled: the section can't be opened or closed, and its header leaves the Tab order. Say why it's unavailable in the header.
Controlling it yourself
To load content first or guard a toggle, listen for tk-toggle and call
preventDefault(), then set open when you're ready. event.detail.open is the state the
section is moving to.
<tk-accordion-item id="reports"><span slot="header">Reports</span><div id="reports-body"></div></tk-accordion-item>
<script>
const item = document.getElementById('reports');
item.addEventListener('tk-toggle', async (e) => {
if (!e.detail.open) return;
e.preventDefault();
await loadReports();
item.open = true;
});
</script>Heading level
Each header is a real heading, level 3 by default. Set heading-level on tk-accordion so
the headings fit your page's outline: under an <h2>, use 3. Set it on one item to
override it for that section.
Used on invoices.
<tk-accordion heading-level="4"> <tk-accordion-item><span slot="header">Billing address</span><p>Used on invoices.</p></tk-accordion-item> </tk-accordion>
When to use
- Use an accordion for long content in sections that people can skip: FAQs, settings groups, product details.
- Don't hide what people must see, such as key instructions, an error, or a required field.
- Use a
Tab bar to switch between views of one area. - Use a
Tree for nested data. An accordion is one level deep. - Use a
Collapsible for a lone show or hide that doesn't need a heading. A one-section accordion is fine when the section needs a heading.
Content
- Make each header short and unique. It also names the section for screen readers, so don't repeat "Details" or "More".
- Use sentence case, with no end punctuation. FAQ headers can be questions.
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Use it for long, skippable content | Hide instructions, errors, or required fields in it |
Set heading-level to fit the page |
Leave headers at the wrong level |
Use single for one-answer-at-a-time FAQs |
Use single when people compare sections |
| Write a unique header for each section | Repeat "Details" in every header |
| Use a tab bar for views of one area | Build tabs out of a single-open accordion |
Related
Collapsible : one show or hide, without a heading.Tab bar : switch between views of one area.Tree : nested data.Dialog : content that must interrupt.
API
tk-accordion attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
single |
boolean | false |
keeps one section open at a time |
heading-level |
number | 3 |
the heading level of every header, 1 to 6 |
tk-accordion-item attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
open |
boolean | false |
the section is open; the property is live |
disabled |
boolean | false |
can't be toggled; the header leaves the Tab order |
heading-level |
number | the container's | overrides the heading level for this section |
Slots
| Element | Slot | Content |
|---|---|---|
tk-accordion |
default | tk-accordion-item sections |
tk-accordion-item |
header |
the section title |
tk-accordion-item |
default | the content |
Events
tk-accordion-item fires tk-toggle when the user opens or closes it, before the state
changes. detail.open is the new state. It bubbles, so you can listen on tk-accordion.
Call preventDefault() to stop the change and set open yourself.
Methods
tk-accordion-item.focus() moves focus to its header.
CSS
tk-accordion-item::part(header): the heading around the trigger.tk-accordion-item::part(trigger): the header<button>.tk-accordion-item::part(panel): the content region.
Tokens
| Element | Token |
|---|---|
| header text | text/default; disabled text/disabled |
| chevron | icon/secondary, icon-size-16 |
| hover, press | state/hover, state/press, with radius-8 |
| focus ring | border/accent/focus, inside the row |
| content text | text/default |
The header uses Label Large (16/24, medium), is at least 48px tall, with space-12 block
padding, space-16 inline padding, and space-8 before the chevron. The content has
space-16 inline and bottom padding. There are no lines between sections; if you need an
edge, put it on the surrounding container. Values per theme:
Accessibility
Built in:
- Each header is a button inside a heading, so screen readers announce it as "Shipping, heading level 3, button, collapsed", and heading navigation reaches every section.
- The button reports whether the section is expanded.
- An open section's content is a region named by its header.
- Closed content is hidden from screen readers and can't be focused.
- The chevron is hidden from screen readers.
- With reduced motion, sections open and close without animation.
Your part:
- Set
heading-levelto fit the page outline. - Keep the number of sections modest: each open section is a landmark region, and dozens of them crowd a screen reader's landmark list.
- On a dark or colored surface, keep the header text at 4.5:1 or more.
| Key | Action |
|---|---|
Tab |
moves to the next header, then into an open section's content |
Enter / Space |
opens or closes the focused section |
Down / Up |
moves to the next or previous enabled header; doesn't wrap |
Home / End |
moves to the first or last enabled header |