Accordion Examples
The examples below assume that you have imported the component and set up the theme.
Basic
Text in the summary slot forms the always-visible header, and everything else becomes the collapsible content.
Orders placed before 2 PM ship the same day. Delivery takes 3 to 5 business days, and a tracking link arrives by email once the package leaves the warehouse.
<div class="accordion-basic"> <sv-accordion> <span slot="summary">Shipping and delivery</span> <p> Orders placed before 2 PM ship the same day. Delivery takes 3 to 5 business days, and a tracking link arrives by email once the package leaves the warehouse. </p> </sv-accordion></div>
<style> .accordion-basic { max-inline-size: 38rem; padding-block: 1em; margin-inline: auto; }</style>Opened and Disabled
opened expands the accordion from markup, and disabled locks it in its current state, open or closed.
Unused items can be sent back within 30 days. Refunds reach the original payment method about a week after the package arrives.
Orders from before 2025 are archived and no longer available here.
<div class="accordion-states"> <sv-accordion disabled opened> <span slot="summary">Returns</span> <p> Unused items can be sent back within 30 days. Refunds reach the original payment method about a week after the package arrives. </p> </sv-accordion>
<sv-accordion disabled> <span slot="summary">Archived orders</span> <p>Orders from before 2025 are archived and no longer available here.</p> </sv-accordion></div>
<style> .accordion-states { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto; }</style>Marker
marker moves the icon to the start or removes it entirely. The end is the default. An icon slotted as marker replaces the chevron and picks up the same size, color, and rotation. Set rotate: none on it to opt out of the rotation.
The icon sits before the summary, and the content is indented under it.
The default position keeps the icon at the far end of the header.
No icon at all, for headers that signal expansion some other way.
The triangle comes from the marker slot, and still rotates when the accordion opens.
<div class="accordion-marker"> <sv-accordion marker="start"> <span slot="summary">Marker at the start</span> <p>The icon sits before the summary, and the content is indented under it.</p> </sv-accordion>
<sv-accordion> <span slot="summary">Marker at the end</span> <p>The default position keeps the icon at the far end of the header.</p> </sv-accordion>
<sv-accordion marker="none"> <span slot="summary">No marker</span> <p>No icon at all, for headers that signal expansion some other way.</p> </sv-accordion>
<sv-accordion> <svg aria-hidden="true" slot="marker" viewBox="0 -960 960 960"> <path d="M480-360 280-560h400L480-360Z" /> </svg>
<span slot="summary">Custom marker</span> <p>The triangle comes from the marker slot, and still rotates when the accordion opens.</p> </sv-accordion></div>
<style> .accordion-marker { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto; }</style>Group
Accordions sharing a group name open one at a time. Opening one closes the rest, anywhere on the page.
Open the sign-in page, choose "Forgot password", and follow the link sent to your inbox.
Usernames can be changed once every 30 days from the account settings page.
Account deletion sits at the bottom of the privacy settings and takes effect after 14 days.
<div class="accordion-group"> <sv-accordion group="faq" opened> <span slot="summary">How do I reset my password?</span> <p>Open the sign-in page, choose "Forgot password", and follow the link sent to your inbox.</p> </sv-accordion>
<sv-accordion group="faq"> <span slot="summary">Can I change my username?</span> <p>Usernames can be changed once every 30 days from the account settings page.</p> </sv-accordion>
<sv-accordion group="faq"> <span slot="summary">How do I delete my account?</span> <p>Account deletion sits at the bottom of the privacy settings and takes effect after 14 days.</p> </sv-accordion></div>
<style> .accordion-group { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto; }</style>Styling
The color, border, and radius tokens the accordion reads can be overridden per element, and the shadow parts cover the rest.
Color tokens tint the header, the content, and the border.
A larger radius token rounds the whole container.
No border, no background, and no inline padding on the parts.
<div class="accordion-styling"> <sv-accordion class="tinted" opened> <span slot="summary">Tinted</span> <p>Color tokens tint the header, the content, and the border.</p> </sv-accordion>
<sv-accordion class="rounded"> <span slot="summary">Rounded</span> <p>A larger radius token rounds the whole container.</p> </sv-accordion>
<sv-accordion class="flat"> <span slot="summary">Flat</span> <p>No border, no background, and no inline padding on the parts.</p> </sv-accordion></div>
<style> .accordion-styling { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto;
.tinted { --sv-accordion-bg: color-mix(in srgb, #22c55e 12%, transparent); --sv-accordion-bdr-clr: color-mix(in srgb, #22c55e 45%, transparent); }
.rounded { --sv-accordion-bdr-rad: 1.25em; }
.flat { --sv-accordion-bg: transparent; --sv-accordion-bdr-sz: 0px;
&::part(trigger), &::part(content) { padding-inline: 0; } } }</style>Animation
--sv-accordion-dur and --sv-accordion-ease reshape the expand transition and the marker rotation together, and a zero duration turns them off. The reduced motion fallback wins over both. The --opened state flips as soon as the accordion toggles, so slotted content can animate alongside the expand.
Your system is set to reduce motion, so this animation will not play for you.
An 800ms ease-in-out expand, easy to follow.
An expo ease that starts fast and glides to a stop.
A zero duration snaps open and closed with no transition.
The paragraph slides and fades in, driven by the accordion's opened state.
<div class="accordion-animation"> <sv-accordion class="slow"> <span slot="summary">Slow</span> <p>An 800ms ease-in-out expand, easy to follow.</p> </sv-accordion>
<sv-accordion class="expo"> <span slot="summary">Expo</span> <p>An expo ease that starts fast and glides to a stop.</p> </sv-accordion>
<sv-accordion class="instant"> <span slot="summary">Instant</span> <p>A zero duration snaps open and closed with no transition.</p> </sv-accordion>
<sv-accordion class="animated"> <span slot="summary">Animated content</span> <p>The paragraph slides and fades in, driven by the accordion's opened state.</p> </sv-accordion></div>
<style> .accordion-animation { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto;
.slow { --sv-accordion-dur: 800ms; --sv-accordion-ease: ease-in-out; }
.expo { --sv-accordion-dur: 500ms; --sv-accordion-ease: cubic-bezier(0.16, 1, 0.3, 1); }
.instant { --sv-accordion-dur: 0s; }
.animated p { opacity: 0; translate: 0 1.5em; transition: opacity 350ms ease, translate 350ms ease; }
.animated:state(--opened) p { opacity: 1; translate: 0 0; } }</style>Programmatic
open, close, and toggle drive the accordion from JavaScript, and each takes an optional flag that skips the animation.
Sign up with an email address, or continue with one of the single sign-on providers.
Click the link in the verification email to activate the account.
Start on the free tier, and upgrade at any time from the billing page.
<div class="accordion-programmatic"> <div class="controls"> <button type="button" data-action="open">Expand all</button> <button type="button" data-action="close">Collapse all</button> </div>
<sv-accordion> <span slot="summary">Create an account</span> <p>Sign up with an email address, or continue with one of the single sign-on providers.</p> </sv-accordion>
<sv-accordion> <span slot="summary">Verify your email</span> <p>Click the link in the verification email to activate the account.</p> </sv-accordion>
<sv-accordion> <span slot="summary">Choose a plan</span> <p>Start on the free tier, and upgrade at any time from the billing page.</p> </sv-accordion></div>
<script type="application/x-typescript" module> const accordions = document.querySelectorAll<Accordion>(".accordion-programmatic sv-accordion");
for (const button of document.querySelectorAll<HTMLButtonElement>(".accordion-programmatic button")) { button.addEventListener("click", () => { for (const accordion of accordions) { const action = button.dataset.action; if (action !== "open" && action !== "close") continue;
accordion[action](); } }); }</script>
<style> .accordion-programmatic { display: grid; gap: 0.75em; max-inline-size: 38rem; padding-block: 1em; margin-inline: auto;
p { margin-block-start: 0; }
.controls { display: flex; gap: 0.5em;
button { padding: 0.2em 1em; font: inherit; color: var(--sv-gray-2); cursor: pointer; background-color: var(--sv-gray-5); border: none; border-radius: var(--sv-bdr-rad-md); } } }</style>