Skip to content

Components / Sections

FAQ

A heading and lead beside a native accordion: one question open at a time, heights animated by the browser, keyboard and screen reader handled by <details>. Zero JavaScript of its own.

Live demo

Questions people actually ask

Short answers. The long ones are in the docs.

Is it really zero JS?

For 67 of 102, yes, measured from a build.

Does it survive View Transitions?

Yes, verified on Astro 5, 6 and 7.

Do I need Tailwind?

No.

Live, from the library itself, at full size: scroll, hover, navigate away and back. The demo is never gated.

Variants · each row writes the attribute the prop writes; the section's own CSS answers

tone
density
align

Measured

JavaScript of its own

0 B

Uses Reveal and the shared runtime (1.9 kB raw, once per site). With those included: 3.0 kB raw.

CSS 9.9 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.

Browser support

Baseline · newly available

Chrome 131 · Firefox 143 · Safari 18.4; needs details-content, allow-discrete, details-name. Elsewhere: questions open and close instantly.

Install Pro

The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:

terminal
npx shadcn@latest add @moonarc-pro/faq-section
src/pages/index.astro
---
import FaqSection from '@/components/moonarc/pro/FaqSection.astro';
---
<FaqSection
  headline="Questions people actually ask"
  copy="Short answers. The long ones are in the docs."
  items={[
    { title: 'Do you ship internationally?', body: '<p>Yes, to 40 countries, tracked.</p>' },
    { title: 'Can I change my order?', body: '<p>Within an hour of placing it, from the confirmation email.</p>' },
  ]}
/>

Without a key the registry answers 401 with an upgrade message. Everything this section composes is free: accordion, reveal.

Props

PropTypeDefaultDescription
items{ title, body }[]noneQuestions; body is an HTML string.
headlinestring'Questions'Section heading.
copystringnoneLead paragraph beside the list.
opennumber0Index open on load.
tone'surface' | 'muted' | 'ink' | 'brand'unset (paints nothing)The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. Each paints --background, --ma-tone-muted (over --muted, with a --border hairline), --ma-tone-ink or --ma-tone-brand (over --primary) with the matching text. With theme.css, a painted tone also re-declares --card, --border, --input and --ring inside the section, so cards and fields follow the ground. Decoration is strongest on brand.
density'compact' | 'cozy' | 'roomy''cozy'Block padding ×0.8 / ×1 / ×1.25 through --ma-density.
align'start' | 'center''start'Heading beside the list, or centred above a narrower list.

Theming and overrides

The section reads the theme contract (shadcn's variable names with the base tokens as fallback), so a pasted theme or one --ma-brand recolours it. Its class names are the override surface and stay stable; a named slot replaces the matching prop with your own markup.

Classes

.ma-faq.ma-faq__aside.ma-faq__copy.ma-faq__eyebrow.ma-faq__head.ma-faq__headline.ma-faq__list

Slots

slot="eyebrow"slot="headline"slot="copy"slot="aside"

Reduced motion

Fades in; questions open instantly.

With ClientRouter

Native; nothing to rebind.

Why it is built this way

Replaces: FAQ sections (Tailwind Plus) · FAQ (shadcnblocks). See the migration table.

Zero JavaScript?

For this one, yes. The browser animates the height.

Keyboard?

Native: Tab, Enter, Space.

One at a time?

details name=, also native.

Native <details> items whose height animates open and closed, with an optional one-at-a-time rule the browser enforces.

newly · Chrome 131 · Firefox 143 · Safari 18.4click

Entrance on scroll that plays once and stays, staggers its children, scrubs with the scroll position when asked, honours reduced motion, and keeps working after every ClientRouter navigation.

every browserscroll

Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown