# Expandable

> Long content clamped to a preview height with a fade and a "Show more" toggle. Zero JS.

URL: https://apogee.avaui.dev/docs/expandable
Last updated: 2026-10-15

Long content clamped to a preview height with a fade and a "Show more" toggle. Zero JS.

Last updated October 15, 2026

```astro
<Expandable maxHeight="6rem">
<p>…long content…</p>
</Expandable>
```

## Add

```sh
npx @ava-ui/apogee add expandable
```

No Apogee dependencies.

## Usage

```astro
---
import Expandable from '@/components/apogee/Expandable/Expandable.astro'
---
<Expandable maxHeight="10rem" moreLabel="Read the full story" lessLabel="Collapse">
  <article>…</article>
</Expandable>
```

The content stays in the DOM at all times; only its visible height changes. Search engines and screen readers see all of it.

## Anatomy

The clamped content block, then a native `<details>` whose `<summary>` is the toggle. Open state is read with `:has()` and applies the clamp to the sibling.

## API

`@composable`. Any other native attribute passes through to the root.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `maxHeight` | `string` | `'8rem'` | Collapsed preview height, any CSS length. |
| `moreLabel` | `string` | `'Show more'` | Toggle text while collapsed. |
| `lessLabel` | `string` | `'Show less'` | Toggle text while expanded. |
| `open` | `boolean` | `false` | Start expanded. |
| `class` | `string` | — | Extra classes on the root, merged last. |

## Variants

```astro
<Expandable maxHeight="4rem">…</Expandable>
<Expandable maxHeight="4rem" open>…</Expandable>
<Expandable maxHeight="4rem" moreLabel="Read on" lessLabel="Enough">…</Expandable>
```

## States

-   **Collapsed** — the content clamps to `maxHeight` with a fade; the toggle shows `moreLabel`.
-   **Expanded** — the full content shows and the toggle shows `lessLabel`.
-   **Reduced motion** — the toggle chevron flips without rotating.

## Examples

Long terms text with custom labels:

```astro
<Expandable maxHeight="5rem" moreLabel="Read all terms" lessLabel="Hide terms" class="max-w-prose text-sm text-neutral">
<p>You can cancel at any time from Settings. We stop billing at the end of the current period and keep your data for 30 days, so you can come back without losing anything.</p>
<p class="mt-2">Refunds cover the unused part of an annual plan. Monthly plans are not refunded. Prices include VAT where it applies.</p>
<p class="mt-2">We may change these terms with 30 days' notice by email.</p>
</Expandable>
```

## Accessibility

-   The toggle is a native `<summary>`: Enter and Space toggle it, and its expanded state is exposed by the browser.
-   Collapsed content is clipped, not removed, so it stays readable to assistive tech. If the clipped part is essential, consider Collapsible instead.
-   Needs `:has()` support (all current browsers). Without it the content shows in full.

## Tokens

| Token | Used for |
| --- | --- |
| `--foreground-primary` | Toggle text |
| `--outline-color-focus` | Focus outline |
| `--duration-medium`, `--ease-standard` | Chevron rotation |

## Do / Don’t

-   **Do** use it for prose: bios, reviews, descriptions.
-   **Don’t** clamp interactive content (forms, tables). Hidden controls confuse everyone.

## Content

-   Toggle labels are verbs: “Show more”, “Read the full review”.

## Related

[

CollapsibleA single show/hide region, built on native <details>. Zero JS.

](https://apogee.avaui.dev/docs/collapsible)[

AccordionA stack of collapsible disclosure panels; expand one to read it, collapse it to reclaim space.

](https://apogee.avaui.dev/docs/accordion)[

ProseTypography styling for a block of rich, CMS, or markdown HTML you don't control element by element.

](https://apogee.avaui.dev/docs/prose)
