---
title: "Accordion"
description: "A vertically stacked set of interactive headings that each reveal an associated section of content."
canonical_url: "https://vinicunca.dev/akar/components/accordion"
---
# Accordion

> A vertically stacked set of interactive headings that each reveal an associated section of content.

```vue [index.vue]
<script setup lang="ts">
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'akar'
import './styles.css'

const accordionItems = [
  {
    value: 'item-1',
    title: 'Is it accessible?',
    content: 'Yes. It adheres to the WAI-ARIA design pattern.',
  },
  {
    value: 'item-2',
    title: 'Is it unstyled?',
    content: 'Yes. It\'s unstyled by default, giving you freedom over the look and feel.',
  },
  {
    value: 'item-3',
    title: 'Can it be animated?',
    content: 'Yes! You can use the transition prop to configure the animation.',
  },
]
</script>

<template>
  <div class="akar-demo akar-demo-Accordion">
    <AccordionRoot
        class="AccordionRoot"
        default-value="item-1"
        type="single"
        :collapsible="true"
      >
        <template
          v-for="item in accordionItems"
          :key="item.value"
        >
          <AccordionItem
            class="AccordionItem"
            :value="item.value"
          >
            <AccordionHeader class="AccordionHeader">
              <AccordionTrigger class="AccordionTrigger">
                <span>{{ item.title }}</span>
                <PIcon
                  name="i-lucide-chevron-down"
                  class="AccordionChevron"
                  aria-label="Expand/Collapse"
                />
              </AccordionTrigger>
            </AccordionHeader>
            <AccordionContent class="AccordionContent">
              <div class="AccordionContentText">
                {{ item.content }}
              </div>
            </AccordionContent>
          </AccordionItem>
        </template>
      </AccordionRoot>
  </div>
</template>
```

```css [styles.css]
@import '../_colors/black-alpha.css';
@import '../_colors/mauve.css';
@import '../_colors/grass.css';

@scope (.akar-demo-Accordion) {
/* reset */
button,
h3 {
  all: unset;
}

.AccordionRoot {
  border-radius: 6px;
  width: 300px;
  background-color: var(--mauve-6);
  box-shadow: 0 2px 10px var(--black-a4);
}

.AccordionItem {
  overflow: hidden;
  margin-top: 1px;
}

.AccordionItem:first-child {
  margin-top: 0;
  border-top-left-radius: 4px;
  border-top-right-radius: 4px;
}

.AccordionItem:last-child {
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

.AccordionItem:focus-within {
  position: relative;
  z-index: 1;
  box-shadow: 0 0 0 2px var(--mauve-12);
}

.AccordionHeader {
  display: flex;
}

.AccordionTrigger {
  font-family: inherit;
  background-color: transparent;
  padding: 0 20px;
  height: 45px;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 15px;
  line-height: 1;
  color: var(--grass-11);
  box-shadow: 0 1px 0 var(--mauve-6);
  background-color: white;
}

.AccordionTrigger:hover {
  background-color: var(--mauve-2);
}

.AccordionContent {
  overflow: hidden;
  font-size: 15px;
  color: var(--mauve-11);
  background-color: var(--mauve-2);
}
.AccordionContent[data-state='open'] {
  animation: slideDown 300ms cubic-bezier(0.87, 0, 0.13, 1);
}
.AccordionContent[data-state='closed'] {
  animation: slideUp 300ms cubic-bezier(0.87, 0, 0.13, 1);
}

.AccordionContentText {
  padding: 15px 20px;
}

.AccordionChevron {
  color: var(--grass-10);
  transition: transform 300ms cubic-bezier(0.87, 0, 0.13, 1);
}
.AccordionTrigger[data-state='open'] > .AccordionChevron {
  transform: rotate(180deg);
}

@keyframes slideDown {
  from {
    height: 0;
  }
  to {
    height: var(--akar-accordion-content-height);
  }
}

@keyframes slideUp {
  from {
    height: var(--akar-accordion-content-height);
  }
  to {
    height: 0;
  }
}
}
```

## Features

- Full keyboard navigation.
- Supports horizontal/vertical orientation.
- Supports Right to Left direction.
- Can expand one or multiple items.
- Can be controlled or uncontrolled.

## Installation

Install the component from your command line.

```bash [pnpm]
pnpm add akar
```

```bash [yarn]
yarn add akar
```

```bash [npm]
npm install akar
```

```bash [bun]
bun add akar
```

## Anatomy

Import all parts and piece them together.

```vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'akar';
</script>

<template>
  <AccordionRoot>
    <AccordionItem>
      <AccordionHeader>
        <AccordionTrigger />
      </AccordionHeader>
      <AccordionContent />
    </AccordionItem>
  </AccordionRoot>
</template>
```

## API Reference

### Root

Contains all the parts of an Accordion

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `collapsible` | `false` | `boolean` | When type is "single", allows closing content when clicking trigger for an open item.<br>When type is "multiple", this prop has no effect. |
| `defaultValue` |  | `T` | The default active value of the item(s).<br><br>Use when you do not need to control the state of the item(s). |
| `dir` | `"ltr"` | `"ltr" \| "rtl"` | The reading direction of the accordion when applicable. If omitted, assumes LTR (left-to-right) reading mode. |
| `disabled` | `false` | `boolean` | When `true`, prevents the user from interacting with the accordion and all its items |
| `modelValue` |  | `T` | The controlled value of the active item(s).<br><br>Use this when you need to control the state of the items. Can be binded with `v-model` |
| `orientation` | `"vertical"` | `"vertical" \| "horizontal"` | The orientation of the accordion. |
| `type` |  | `"single" \| "multiple"` | Determines whether a "single" or "multiple" items can be selected at a time.<br><br>This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
| `unmountOnHide` | `true` | `boolean` | When `true`, the element will be unmounted on closed state. |

**Events**

| Event | Payload | Description |
| --- | --- | --- |
| `update:modelValue` | `value: (ExplicitType extends "single" ? string : string[])` | Event handler called when the expanded state of an item changes |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `modelValue` | `AcceptableValue \| AcceptableValue[]` | Current active value |

[AccordionRoot.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion/AccordionRoot.vue)

| Data attribute | Value |
| --- | --- |
| `[data-orientation]` | "vertical" \\| "horizontal" |

### Item

Contains all the parts of a collapsible section.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `disabled` | `false` | `boolean` | Whether or not an accordion item is disabled from user interaction.<br>When `true`, prevents the user from interacting with the item. |
| `unmountOnHide` |  | `boolean` | When `true`, the element will be unmounted on closed state. |
| `value*` |  | `string` | A string value for the accordion item. All items within an accordion should use a unique value. |

**Slots**

| Slot | Payload | Description |
| --- | --- | --- |
| `open` | `boolean` | Current open state |

[AccordionItem.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion/AccordionItem.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | "vertical" \\| "horizontal" |

### Header

Wraps an `AccordionTrigger`. Use the `asChild` prop to update it to the appropriate heading level for your page.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"h3"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AccordionHeader.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion/AccordionHeader.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | "vertical" \\| "horizontal" |

### Trigger

Toggles the collapsed state of its associated item. It should be nested inside of an `AccordionHeader`.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |

[AccordionTrigger.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion/AccordionTrigger.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | "vertical" \\| "horizontal" |

### Content

Contains the collapsible content for an item.

**Props**

| Prop | Default | Type | Description |
| --- | --- | --- | --- |
| `as` | `"div"` | `AsTag \| Component` | The element or component this component should render as. Can be overwritten by `asChild`. |
| `asChild` |  | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior.<br><br>Read our [Composition](https://vinicunca.dev/akar/guides/composition) guide for more details. |
| `forceMount` |  | `boolean` | Used to force mounting when more control is needed. Useful when<br>controlling animation with Vue animation libraries. |

[AccordionContent.vue source](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion/AccordionContent.vue)

| Data attribute | Value |
| --- | --- |
| `[data-state]` | "open" \\| "closed" |
| `[data-disabled]` | Present when disabled |
| `[data-orientation]` | "vertical" \\| "horizontal" |

| CSS variable | Description |
| --- | --- |
| `--akar-accordion-content-width` | The width of the content when it opens/closes |
| `--akar-accordion-content-height` | The height of the content when it opens/closes |

## Examples

### Expanded by default

Use the `defaultValue` prop to define the open item by default.

```vue
<template>
  <AccordionRoot
    type="single"
    default-value="item-2"
  >
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>
```

### Allow collapsing all items

Use the `collapsible` prop to allow all items to close.

```vue
<template>
  <AccordionRoot
    type="single"
    collapsible
  >
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>
```

### Multiple items open at the same time

Set the `type` prop to `multiple` to enable opening multiple items at once.

```vue
<template>
  <AccordionRoot type="multiple">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>
```

### Rotated icon when open

You can add extra decorative elements, such as chevrons, and rotate it when the item is open.

```vue
// index.vue
<script setup>
import { Icon } from '@iconify/vue'
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'akar'
import './styles.css'
</script>

<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader>
        <AccordionTrigger class="AccordionTrigger">
          Trigger text
          <Icon
            icon="radix-icons:chevron-down"
            class="AccordionChevron"
          />
        </AccordionTrigger>
      </AccordionHeader>
      <AccordionContent>…</AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>
```

```css
/* styles.css */
.AccordionChevron {
  transition: transform 300ms;
}
.AccordionTrigger[data-state="open"] > .AccordionChevron {
  transform: rotate(180deg);
}
```

### Horizontal orientation

Use the `orientation` prop to create a horizontal Accordion

```vue
<template>
  <AccordionRoot orientation="horizontal">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>
```

### Animating content size

Use the `--akar-accordion-content-width` and/or `--akar-accordion-content-height` CSS variables to animate the size of the content when it opens/closes:

```vue
// index.vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'akar'
import './styles.css'
</script>

<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader>…</AccordionHeader>
      <AccordionContent class="AccordionContent">
        …
      </AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>
```

```css
/* styles.css */
.AccordionContent {
  overflow: hidden;
}
.AccordionContent[data-state="open"] {
  animation: slideDown 300ms ease-out;
}
.AccordionContent[data-state="closed"] {
  animation: slideUp 300ms ease-out;
}

@keyframes slideDown {
  from {
    height: 0;
  }
  to {
    height: var(--akar-accordion-content-height);
  }
}

@keyframes slideUp {
  from {
    height: var(--akar-accordion-content-height);
  }
  to {
    height: 0;
  }
}
```

### Render content even when closed

By default hidden content will be removed, use `:unmountOnHide="false"` to keep the content always available.

This will also allow browser to search the hidden text, and open the accordion.

```vue
<template>
  <AccordionRoot :unmount-on-hide="false">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>
```

## Accessibility

Adheres to the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion).

### Keyboard Interactions

| Key | Description |
| --- | --- |
| <kbd>Space</kbd> | When focus is on an `AccordionTrigger` of a collapsed section, expands the section. |
| <kbd>Enter</kbd> | When focus is on an `AccordionTrigger` of a collapsed section, expands the section. |
| <kbd>Tab</kbd> | Moves focus to the next focusable element. |
| <kbd>Shift + Tab</kbd> | Moves focus to the previous focusable element. |
| <kbd>ArrowDown</kbd> | Moves focus to the next `AccordionTrigger` when `orientation` is `vertical`. |
| <kbd>ArrowUp</kbd> | Moves focus to the previous `AccordionTrigger` when `orientation` is `vertical`. |
| <kbd>ArrowRight</kbd> | Moves focus to the next `AccordionTrigger` when `orientation` is `horizontal`. |
| <kbd>ArrowLeft</kbd> | Moves focus to the previous `AccordionTrigger` when `orientation` is `horizontal`. |
| <kbd>Home</kbd> | When focus is on an `AccordionTrigger`, moves focus to the start `AccordionTrigger`. |
| <kbd>End</kbd> | When focus is on an `AccordionTrigger`, moves focus to the last `AccordionTrigger`. |

---

- [ARIA](https://www.w3.org/WAI/ARIA/apg/patterns/accordion)
- [GitHub](https://github.com/vinicunca/akar/blob/v2.0.20/packages/core/src/Accordion)
- [npm](https://www.npmjs.com/package/akar)


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
