Blocks · Marketing
FAQ
Questions as native details: keyboard, find-in-page and no JavaScript.
29% of the 2,062 sites in The UI Index have a accordion (590 sites).
Questions
Can't find an answer? Write to us and we reply within a day.
Can I use it in client work?
Yes. Use it in as many personal and commercial projects as you like.
Does it work without React?
Every item comes as React, Astro and plain HTML, with the same classes and the same DOM.
How do I change the colours?
Change the CSS variables in your theme file. The names are the ones shadcn/ui uses, so any shadcn theme works too.
Questions
Can't find an answer? Write to us and we reply within a day.
Can I use it in client work?
Yes. Use it in as many personal and commercial projects as you like.
Does it work without React?
Every item comes as React, Astro and plain HTML, with the same classes and the same DOM.
How do I change the colours?
Change the CSS variables in your theme file. The names are the ones shadcn/ui uses, so any shadcn theme works too.
Both previews render the same markup; the HTML tab below is that markup without a framework.
Install
- React
- npx shadcn@
latest add https:// www.themes.dev/ caseroom/ r/ faq.json - Astro
- npx shadcn@
latest add https:// www.themes.dev/ caseroom/ r/ astro/ faq.json
Or copy the files below into your project. They need clsx, tailwind-merge and the components they import, and the Caseroom theme. The HTML needs only the compiled CSS.
export const faq = {
root: '@container bg-background px-4 py-20 sm:px-6 sm:py-24',
inner: 'mx-auto grid max-w-5xl gap-10 @3xl:grid-cols-[1fr_1.6fr]',
title: 'text-3xl font-semibold tracking-[-0.03em] text-balance',
description: 'mt-4 text-base text-pretty text-muted-foreground',
// Questions sit on their own grounds, separated by space, not by rules; an open one deepens.
list: 'grid gap-2',
item: 'group rounded-lg bg-muted/60 px-4 @md:px-5 transition-colors open:bg-muted has-[summary:active]:bg-pressed',
summary:
'-mx-4 flex cursor-pointer list-none items-center justify-between gap-4 rounded-lg px-4 py-4 text-[15px] font-medium text-pretty @md:-mx-5 @md:px-5 transition-colors hover:bg-accent active:bg-pressed [&::-webkit-details-marker]:hidden',
icon: 'size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-45',
answer: 'pb-5 pr-8 text-sm text-pretty text-muted-foreground',
};
export type FaqContent = { title: string; description?: string; items: { question: string; answer: string }[] };import { cn } from '@/lib/utils';
import { faq, type FaqContent } from './faq.classes';
export type FaqProps = FaqContent & { className?: string };
/** Questions as native <details>: they open with the keyboard, in find-in-page and without JavaScript. */
export function Faq({ title, description, items, className }: FaqProps) {
return (
<section className={cn(faq.root, className)}>
<div className={faq.inner}>
<div>
<h2 className={faq.title}>{title}</h2>
{description && <p className={faq.description}>{description}</p>}
</div>
<div className={faq.list}>
{items.map((item) => (
<details key={item.question} className={faq.item}>
<summary className={faq.summary}>
{item.question}
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" aria-hidden="true" className={faq.icon}>
<path d="M8 3v10M3 8h10" />
</svg>
</summary>
<p className={faq.answer}>{item.answer}</p>
</details>
))}
</div>
</div>
</section>
);
}---
import { cn } from '@/lib/utils';
import { faq, type FaqContent } from './faq.classes';
type Props = FaqContent & { class?: string };
const { title, description, items, class: className } = Astro.props;
---
<section class={cn(faq.root, className)}>
<div class={faq.inner}>
<div>
<h2 class={faq.title}>{title}</h2>
{description && <p class={faq.description}>{description}</p>}
</div>
<div class={faq.list}>
{
items.map((item) => (
<details class={faq.item}>
<summary class={faq.summary}>
{item.question}
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true" class={faq.icon}>
<path d="M8 3v10M3 8h10" />
</svg>
</summary>
<p class={faq.answer}>{item.answer}</p>
</details>
))
}
</div>
</div>
</section>export const faq = {
root: '@container bg-background px-4 py-20 sm:px-6 sm:py-24',
inner: 'mx-auto grid max-w-5xl gap-10 @3xl:grid-cols-[1fr_1.6fr]',
title: 'text-3xl font-semibold tracking-[-0.03em] text-balance',
description: 'mt-4 text-base text-pretty text-muted-foreground',
// Questions sit on their own grounds, separated by space, not by rules; an open one deepens.
list: 'grid gap-2',
item: 'group rounded-lg bg-muted/60 px-4 @md:px-5 transition-colors open:bg-muted has-[summary:active]:bg-pressed',
summary:
'-mx-4 flex cursor-pointer list-none items-center justify-between gap-4 rounded-lg px-4 py-4 text-[15px] font-medium text-pretty @md:-mx-5 @md:px-5 transition-colors hover:bg-accent active:bg-pressed [&::-webkit-details-marker]:hidden',
icon: 'size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-45',
answer: 'pb-5 pr-8 text-sm text-pretty text-muted-foreground',
};
export type FaqContent = { title: string; description?: string; items: { question: string; answer: string }[] };<section class="@container bg-background px-4 py-20 sm:px-6 sm:py-24">
<div class="mx-auto grid max-w-5xl gap-10 @3xl:grid-cols-[1fr_1.6fr]">
<div>
<h2 class="text-3xl font-semibold tracking-[-0.03em] text-balance">Questions</h2>
<p class="mt-4 text-base text-pretty text-muted-foreground">Can't find an answer? Write to us and we reply within a day.</p>
</div>
<div class="grid gap-2">
<details class="group rounded-lg bg-muted/60 px-4 @md:px-5 transition-colors open:bg-muted has-[summary:active]:bg-pressed">
<summary class="-mx-4 flex cursor-pointer list-none items-center justify-between gap-4 rounded-lg px-4 py-4 text-[15px] font-medium text-pretty @md:-mx-5 @md:px-5 transition-colors hover:bg-accent active:bg-pressed [&::-webkit-details-marker]:hidden">
Can I use it in client work?
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-45"><path d="M8 3v10M3 8h10"></path></svg>
</summary>
<p class="pb-5 pr-8 text-sm text-pretty text-muted-foreground">Yes. Use it in as many personal and commercial projects as you like.</p>
</details>
<details class="group rounded-lg bg-muted/60 px-4 @md:px-5 transition-colors open:bg-muted has-[summary:active]:bg-pressed">
<summary class="-mx-4 flex cursor-pointer list-none items-center justify-between gap-4 rounded-lg px-4 py-4 text-[15px] font-medium text-pretty @md:-mx-5 @md:px-5 transition-colors hover:bg-accent active:bg-pressed [&::-webkit-details-marker]:hidden">
Does it work without React?
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-45"><path d="M8 3v10M3 8h10"></path></svg>
</summary>
<p class="pb-5 pr-8 text-sm text-pretty text-muted-foreground">Every item comes as React, Astro and plain HTML, with the same classes and the same DOM.</p>
</details>
<details class="group rounded-lg bg-muted/60 px-4 @md:px-5 transition-colors open:bg-muted has-[summary:active]:bg-pressed">
<summary class="-mx-4 flex cursor-pointer list-none items-center justify-between gap-4 rounded-lg px-4 py-4 text-[15px] font-medium text-pretty @md:-mx-5 @md:px-5 transition-colors hover:bg-accent active:bg-pressed [&::-webkit-details-marker]:hidden">
How do I change the colours?
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" aria-hidden="true" class="size-4 shrink-0 text-muted-foreground transition-transform group-open:rotate-45"><path d="M8 3v10M3 8h10"></path></svg>
</summary>
<p class="pb-5 pr-8 text-sm text-pretty text-muted-foreground">
Change the CSS variables in your theme file. The names are the ones shadcn/ui uses, so any shadcn theme works too.
</p>
</details>
</div>
</div>
</section>