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

Last updated

The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences. The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences. The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences.

Show moreShow less
Show code
<Expandable maxHeight="6rem">
<p>…long content…</p>
</Expandable>

Add

npx @ava-ui/apogee add expandable

No Apogee dependencies.

Usage

---
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

The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences. The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences.

Show moreShow less

The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences. The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences.

Show moreShow less

The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences. The Apogee design system ships components you copy into your project and own. Every visual value reads a token, every control is a native element first, and JavaScript is progressive enhancement. Components mirror automatically under a right-to-left ancestor, pass the contrast gate in both themes, and respect reduced-motion preferences.

Read onEnough
Show code
<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:

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.

Refunds cover the unused part of an annual plan. Monthly plans are not refunded. Prices include VAT where it applies.

We may change these terms with 30 days’ notice by email.

Read all termsHide terms
Show code
<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”.