---
title: Collapsible
description: A single show/hide disclosure — one trigger toggles one region
related:
  - /components/accordion
  - /components/faq
  - /components/reveal
visibility: guest
draft: false
---

# Collapsible

A standalone disclosure: one trigger that shows and hides one region of content. It is the bare [WAI-ARIA Disclosure pattern](https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/) with no surrounding chrome.

::: info Collapsible vs Accordion vs FAQ — when to use which

- **Collapsible** (this component) — a *single* independent show/hide: a "read more", an advanced-options panel. Stack several for loosely-related toggles that need **no coordination** and no card chrome.
- **[Accordion](/components/accordion)** — a *coordinated group* of panels with optional single-open behavior and card chrome. Reach for it when opening one panel should be able to close the others.
- **[FAQ](/components/faq)** — an accordion specialized for questions that also emits [FAQPage](/components/structured-data) structured data derived from what it renders. Use it for a real question list.
- **[Reveal](/components/reveal)** — for scroll- or load-triggered entrance *animation*, not a user toggle.
:::

## Basic Usage

The default slot is the collapsible content; `trigger` is the clickable label.

Collapsible is block-level — it fills its container's width, and that width does **not** change as it opens or closes (watch the previews below stay put; in your app it spans whatever column you place it in).

:::preview{title="Show / hide a panel"}
<x-wirekit::collapsible style="width: 24rem; max-width: 100%" trigger="What is your refund policy?">
    <x-wirekit::text>We offer a 30-day money-back guarantee on all plans, no questions asked.</x-wirekit::text>
</x-wirekit::collapsible>
:::

## Open by Default

Pass `:open="true"` to render the region expanded on first paint.

:::preview{title="Initially open"}
<x-wirekit::collapsible style="width: 24rem; max-width: 100%" trigger="Shipping details" :open="true">
    <x-wirekit::text>Orders ship within 2 business days. Tracking is emailed once your parcel leaves the warehouse.</x-wirekit::text>
</x-wirekit::collapsible>
:::

## Rich Trigger

For a trigger that needs an icon or markup, use a `<x-slot:trigger>` instead of the string prop.

:::preview{title="Trigger with an icon"}
<x-wirekit::collapsible style="width: 24rem; max-width: 100%">
    <x-slot:trigger>
        <x-wirekit::row gap="sm" style="align-items: center;">
            <x-wirekit::icon name="adjustments-horizontal" class="h-4 w-4" />
            <x-wirekit::text weight="medium">Advanced options</x-wirekit::text>
        </x-wirekit::row>
    </x-slot:trigger>
    <x-wirekit::stack gap="sm">
        <x-wirekit::checkbox name="opt-cache" label="Enable response caching" />
        <x-wirekit::checkbox name="opt-minify" label="Minify HTML output" />
    </x-wirekit::stack>
</x-wirekit::collapsible>
:::

## In Context — an FAQ

The most common use: a stack of independent disclosures. Width stays put as items open and close.

:::preview{title="FAQ list"}
<x-wirekit::stack style="width: 30rem; max-width: 100%" gap="md">
    <x-wirekit::collapsible trigger="Can I change plans later?">
        <x-wirekit::text>Yes — upgrade or downgrade anytime from Billing. Changes are prorated to the day.</x-wirekit::text>
    </x-wirekit::collapsible>
    <x-wirekit::divider />
    <x-wirekit::collapsible trigger="Do you offer team seats?">
        <x-wirekit::text>Every paid plan includes unlimited seats. Invite teammates from Settings → Members.</x-wirekit::text>
    </x-wirekit::collapsible>
    <x-wirekit::divider />
    <x-wirekit::collapsible trigger="Is my data exportable?">
        <x-wirekit::text>Export everything to CSV or JSON at any time — your data is never locked in.</x-wirekit::text>
    </x-wirekit::collapsible>
</x-wirekit::stack>
:::

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `trigger` | string\|null | `null` | The trigger label. For rich content, use a `<x-slot:trigger>` instead. |
| `open` | bool | `false` | Whether the region starts expanded |
| `scope` | string\|null | `null` | Scoped personalization name |

## Accessibility

- The trigger is a native `<button>`, so it is keyboard-focusable and operable out of the box.
- `aria-expanded` reflects the open/closed state; `aria-controls` links the trigger to the region it toggles.
- The chevron is decorative (`aria-hidden="true"`).
- The region animates open/closed via Alpine's `x-collapse`, which respects `prefers-reduced-motion`.

## Keyboard Interaction

| Key | Action |
| --- | --- |
| `Tab` | Move focus to the trigger |
| `Enter` / `Space` | Toggle the region open or closed |

## Design Tokens

| Token | Used for |
| --- | --- |
| `--color-wk-text` | Trigger + content text |
| `--color-wk-ring` | Trigger focus ring |
| `--radius-wk-sm` | Trigger focus-ring corner radius |
| `--transition-wk-duration` | Chevron rotation timing |
| `--padding-wk-y-md` | Gap between trigger and content |
