Accordion
A stacked set of disclosure panels using the native details/summary elements.
Usage
Is ZUI free to use?
Yes, ZUI is open source and free to use in any project.
Which frameworks does ZUI support?
ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.
Does ZUI support dark mode?
Yes, all components use light-dark() and CSS custom properties for automatic theme switching.
<div class="zui-accordion">
<details class="zui-accordion-item">
<summary class="zui-accordion-trigger">Is ZUI free to use?</summary>
<div class="zui-accordion-content">
<p>Yes, ZUI is open source and free to use in any project.</p>
</div>
</details>
<details class="zui-accordion-item">
<summary class="zui-accordion-trigger">Which frameworks does ZUI support?</summary>
<div class="zui-accordion-content">
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</div>
</details>
<details class="zui-accordion-item">
<summary class="zui-accordion-trigger">Does ZUI support dark mode?</summary>
<div class="zui-accordion-content">
<p>Yes, all components use <code>light-dark()</code> and CSS custom properties for automatic theme switching.</p>
</div>
</details>
</div> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/react'
<Accordion>
<AccordionItem>
<AccordionTrigger>Is ZUI free to use?</AccordionTrigger>
<AccordionContent>
<p>Yes, ZUI is open source and free to use in any project.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Which frameworks does ZUI support?</AccordionTrigger>
<AccordionContent>
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Does ZUI support dark mode?</AccordionTrigger>
<AccordionContent>
<p>Yes, all components use light-dark() and CSS custom properties for automatic theme switching.</p>
</AccordionContent>
</AccordionItem>
</Accordion> ---
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/astro'
---
<Accordion>
<AccordionItem>
<AccordionTrigger>Is ZUI free to use?</AccordionTrigger>
<AccordionContent>
<p>Yes, ZUI is open source and free to use in any project.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Which frameworks does ZUI support?</AccordionTrigger>
<AccordionContent>
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Does ZUI support dark mode?</AccordionTrigger>
<AccordionContent>
<p>Yes, all components use light-dark() and CSS custom properties for automatic theme switching.</p>
</AccordionContent>
</AccordionItem>
</Accordion> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/solid'
<Accordion>
<AccordionItem>
<AccordionTrigger>Is ZUI free to use?</AccordionTrigger>
<AccordionContent>
<p>Yes, ZUI is open source and free to use in any project.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Which frameworks does ZUI support?</AccordionTrigger>
<AccordionContent>
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Does ZUI support dark mode?</AccordionTrigger>
<AccordionContent>
<p>Yes, all components use light-dark() and CSS custom properties for automatic theme switching.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <script lang="ts">
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/svelte'
</script>
<Accordion>
<AccordionItem>
<AccordionTrigger>Is ZUI free to use?</AccordionTrigger>
<AccordionContent>
<p>Yes, ZUI is open source and free to use in any project.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Which frameworks does ZUI support?</AccordionTrigger>
<AccordionContent>
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Does ZUI support dark mode?</AccordionTrigger>
<AccordionContent>
<p>Yes, all components use light-dark() and CSS custom properties for automatic theme switching.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <template>
<Accordion>
<AccordionItem>
<AccordionTrigger>Is ZUI free to use?</AccordionTrigger>
<AccordionContent>
<p>Yes, ZUI is open source and free to use in any project.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Which frameworks does ZUI support?</AccordionTrigger>
<AccordionContent>
<p>ZUI provides CSS classes for any framework, plus first-class React, Astro, Solid, Svelte, and Vue component wrappers.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Does ZUI support dark mode?</AccordionTrigger>
<AccordionContent>
<p>Yes, all components use light-dark() and CSS custom properties for automatic theme switching.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</template>
<script setup>
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/vue'
</script> Exclusive (only one open at a time)
Add a shared name attribute to <details> items to get native exclusive accordion behaviour — only one panel can be open at a time.
First item
Opening another item will close this one.
Second item
Only one item can be open at a time thanks to the shared name attribute.
Third item
This is native browser behaviour — no JavaScript needed.
<div class="zui-accordion">
<details class="zui-accordion-item" name="faq">
<summary class="zui-accordion-trigger">First item</summary>
<div class="zui-accordion-content">
<p>Opening another item will close this one.</p>
</div>
</details>
<details class="zui-accordion-item" name="faq">
<summary class="zui-accordion-trigger">Second item</summary>
<div class="zui-accordion-content">
<p>Only one item can be open at a time thanks to the shared <code>name</code> attribute.</p>
</div>
</details>
<details class="zui-accordion-item" name="faq">
<summary class="zui-accordion-trigger">Third item</summary>
<div class="zui-accordion-content">
<p>This is native browser behaviour — no JavaScript needed.</p>
</div>
</details>
</div> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/react'
<Accordion>
<AccordionItem name="faq">
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Opening another item will close this one.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>Only one item can be open at a time thanks to the shared name attribute.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Third item</AccordionTrigger>
<AccordionContent>
<p>This is native browser behaviour — no JavaScript needed.</p>
</AccordionContent>
</AccordionItem>
</Accordion> ---
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/astro'
---
<Accordion>
<AccordionItem name="faq">
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Opening another item will close this one.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>Only one item can be open at a time thanks to the shared name attribute.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Third item</AccordionTrigger>
<AccordionContent>
<p>This is native browser behaviour — no JavaScript needed.</p>
</AccordionContent>
</AccordionItem>
</Accordion> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/solid'
<Accordion>
<AccordionItem name="faq">
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Opening another item will close this one.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>Only one item can be open at a time thanks to the shared name attribute.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Third item</AccordionTrigger>
<AccordionContent>
<p>This is native browser behaviour — no JavaScript needed.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <script lang="ts">
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/svelte'
</script>
<Accordion>
<AccordionItem name="faq">
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Opening another item will close this one.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>Only one item can be open at a time thanks to the shared name attribute.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Third item</AccordionTrigger>
<AccordionContent>
<p>This is native browser behaviour — no JavaScript needed.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <template>
<Accordion>
<AccordionItem name="faq">
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Opening another item will close this one.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>Only one item can be open at a time thanks to the shared name attribute.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem name="faq">
<AccordionTrigger>Third item</AccordionTrigger>
<AccordionContent>
<p>This is native browser behaviour — no JavaScript needed.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</template>
<script setup>
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/vue'
</script> Flush variant
Remove the outer border and background, leaving only the item dividers.
First item
Flush accordions blend into the surrounding layout.
Second item
No outer border or background.
<div class="zui-accordion zui-accordion-flush">
<details class="zui-accordion-item">
<summary class="zui-accordion-trigger">First item</summary>
<div class="zui-accordion-content">
<p>Flush accordions blend into the surrounding layout.</p>
</div>
</details>
<details class="zui-accordion-item">
<summary class="zui-accordion-trigger">Second item</summary>
<div class="zui-accordion-content">
<p>No outer border or background.</p>
</div>
</details>
</div> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/react'
<Accordion flush>
<AccordionItem>
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Flush accordions blend into the surrounding layout.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>No outer border or background.</p>
</AccordionContent>
</AccordionItem>
</Accordion> ---
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/astro'
---
<Accordion flush>
<AccordionItem>
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Flush accordions blend into the surrounding layout.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>No outer border or background.</p>
</AccordionContent>
</AccordionItem>
</Accordion> import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/solid'
<Accordion flush>
<AccordionItem>
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Flush accordions blend into the surrounding layout.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>No outer border or background.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <script lang="ts">
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/svelte'
</script>
<Accordion flush>
<AccordionItem>
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Flush accordions blend into the surrounding layout.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>No outer border or background.</p>
</AccordionContent>
</AccordionItem>
</Accordion> <template>
<Accordion flush>
<AccordionItem>
<AccordionTrigger>First item</AccordionTrigger>
<AccordionContent>
<p>Flush accordions blend into the surrounding layout.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem>
<AccordionTrigger>Second item</AccordionTrigger>
<AccordionContent>
<p>No outer border or background.</p>
</AccordionContent>
</AccordionItem>
</Accordion>
</template>
<script setup>
import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@mrmartineau/zui/vue'
</script> CSS custom properties
| Property | Default | Description |
|---|---|---|
--zui-accordion-border | var(--color-border) | Border colour |
--zui-accordion-radius | var(--radius-md) | Border radius |
--zui-accordion-bg | var(--color-surface) | Background colour |
--zui-accordion-padding-x | var(--space-sm) | Horizontal padding |
--zui-accordion-padding-y | var(--space-sm) | Vertical padding |