Building the whole landing page, not just this section?
You just browsed 25 Tailwind faq accordion. Cruip makes complete Tailwind CSS templates for landing pages, SaaS websites and admin dashboards, coded in HTML, React, Next.js and Vue and used by 60K+ developers. Single templates start at $49.
The checkbox hack, ported whole: a peer checkbox holds the open state, its <label> is the question row, and peer-checked:grid-rows-[1fr] animates the answer to its natural height. This is the one accordion pattern that needs no CSS block at all — the 0fr→1fr trick is fully expressible in utilities, so the entire disclosure lives in the markup.
The most semantic FAQ possible, in utilities: native <details>/<summary> for behaviour, group-open: for every open-state style, and the marker killed by list-none [&::-webkit-details-marker]:hidden. The height-to-auto animation is the one thing utilities cannot reach, so it stays four lines of @supports CSS — enhancing every accordion on the page at once. Styled as a warm editorial help page.
Only-one-open used to mean JavaScript closing siblings; now it is one HTML attribute. Give every <details> the same name and the browser enforces exclusivity like radio buttons. The port's contribution is the attention choreography: has-[details[open]]: on the list dims the closed questions, which is :has() written where you can see it.
The comparison-friendly FAQ: every panel opens independently, so users can read three answers side by side — the pattern research keeps showing beats only-one-open for comprehension tasks. On top sits a live "N of 6 open" chip driven entirely by CSS counters and has-checked: — genuinely JS-free UI state, and the one demo where Tailwind's arbitrary-property escape hatch is the whole technique.
The house-style SaaS FAQ, and the demo where the port stops being a port: in the CSS collection this entry shipped a hand-compiled stylesheet imitating Tailwind, and here it is simply real Tailwind. Indigo on white, native <details class="group">, divide-y for the rules between rows, a full dark: track, and no plugin, no config extension, no JavaScript.
The counter-argument to dark:. Every colour is declared once as a light-dark() pair inside @theme, and a single color-scheme flip re-skins the whole component — including native scrollbars, form controls and selection colours that a .dark class never reaches. A true two-way switch that starts from the visitor's OS preference, with zero duplicated utilities, a small seed script, and a View Transition cross-fade.
Newsletter
Enjoying these demos? Get new ones by email.
A short email when a new collection ships. Unsubscribe any time.
Frosted-glass panels floating over a photographic backdrop. Tailwind has utilities for all four glass layers — the tint, backdrop-blur-[18px] backdrop-saturate-150, a translucent border and an inset highlight inside shadow-[...] — so the whole material is a class list, and the open state simply frosts deeper. Includes the two rules most glassmorphism tutorials miss: the saturation boost and the top-edge highlight.
The product-page FAQ that converts: shipping, returns and care answers in a bone-white, hairline-divided accordion beside the product photo — the layout premium DTC brands and every good Shopify theme use. The port's real gain is the breakpoint: @container plus @3xl: variants mean the FAQ reflows when the component is narrow, in a theme sidebar or a modal, not when the viewport says so.
Soft-UI done responsibly: cards extruded from a single-material surface with the twin-shadow trick (light top-left, shade bottom-right), pressing physically inset when opened — the material metaphor doing the state communication. Both shadow colours are color-mix() derivations of one surface token, so retheming is a one-line edit, and the two fixes that make neumorphism shippable are baked in.
The technique demo: how grid-template-rows: 0fr → 1fr finally solved CSS's oldest animation problem — transitioning to height:auto — written entirely in utilities. This FAQ dissects its own animation: every open panel carries a live annotation of what the track is doing, and the answers explain why max-height hacks break and why the one overflow-hidden wrapper is mandatory.
The definitive treatment of the web's most-copied micro-interaction, ported: three chevron builds in one FAQ — inline SVG, a two-border CSS chevron, and a Unicode glyph — each rotating on group-open: with matched timing, plus the UX rules for which way a closed chevron should point and why the rotation duration must equal the panel's.
The +/− morph elevated from “the vertical bar fades out” to choreography: both bars rotate a half-turn together while the vertical one collapses along its own length, so the glyph appears to twist itself into a minus. Two before:/after: bars, no SVG, no icon font — and Tailwind's pseudo-element variants make the whole thing a class list.
Spring physics without a physics engine: linear() plays back a real damped-spring curve — overshoot, wobble, settle — and in v4 it becomes a utility the moment you name it --ease-tfa13-spring in @theme. Panels bounce open like they have mass, the icon over-rotates and recoils, and closing stays deliberately calm.
A wide FAQ split into two independent columns — the layout every marketing site wants past eight questions — built so an opening panel pushes down only its own column, never its horizontal neighbour. The trap almost everyone hits is one flat grid of items, where row alignment makes cells stretch each other; the fix is two column containers, and it is two utilities.
Newsletter
Enjoying these demos? Get new ones by email.
A short email when a new collection ships. Unsubscribe any time.
The showpiece: five photo panels standing shoulder to shoulder, the active one unfolding sideways to reveal its answer while the others compress into spines with vertically-written titles. Demo 10's fr-unit trick rotated 90° — grid-cols-[64px_0fr] to [64px_1fr] — plus a grow-[3.2] transition, [writing-mode:vertical-rl] spines, and radio state, so it stays pure Tailwind.
The help-centre layout: questions grouped under category headings with a sticky sidebar that jumps between sections. Every piece of navigation is native — sticky top-6 self-start pins the menu, scroll-mt-6 stops headings hiding under the top edge, scroll-smooth makes jumps glide — and the two rules people always miss are now visible in the class list rather than buried in a stylesheet.
Separated FAQ cards with a real elevation system: three levels (resting, hover, open) built from layered shadows that mimic how light actually falls — a tight dark contact layer plus a wide soft ambient one — instead of the single fuzzy grey blob of tutorial CSS. Cards lift 2px on hover and rise to full elevation when open, with the shadow tinted in the page's own hue rather than black.
Type-to-filter FAQ: the search bar live-narrows the list, matching question and answer text, auto-expanding hits so the match is visible, announcing a count through aria-live, and showing a designed no-results state. Twenty-four lines of dependency-free JS on top of native <details> — and the search bar's focus ring is the port's quiet win.
The bulk controls every long FAQ needs — Expand all / Collapse all over a native <details> list, for readers who skim, Ctrl+F or print. Fourteen lines of JS loop the open attribute; the interesting engineering is state truthfulness (each button disables when it would do nothing), and the print layer is now a print: variant instead of a media query.
The conversion completion of every FAQ: a “Still have questions?” card that catches the users your answers did not — the difference between a dead-end page and a support funnel. A warm gradient panel with an overlapping avatar group (the real-humans-reply trust signal), a response-time promise, and exactly two actions in clear hierarchy.
The WAI-ARIA Authoring Practices accordion, implemented exactly: real headings wrapping real buttons with aria-expanded and aria-controls, labelled regions for the panels, and the full keyboard layer — arrows cycle between headers, Home/End jump to the ends, Enter/Space toggle. The port's best property is that every visual state keys off the accessibility attribute, so what is announced and what is shown cannot drift apart.
A FAQ wearing its structured data: the visible accordion is mirrored 1:1 by a FAQPage JSON-LD block in the same component, making answers parseable by search engines and — increasingly the point — by AI answer engines. Includes a mock SERP preview of the rich result, and the eligibility reality check for 2026.
Newsletter
Enjoying these demos? Get new ones by email.
A short email when a new collection ships. Unsubscribe any time.
The migration demo. Bootstrap's accordion needs bootstrap.bundle.js, a data-bs-parent wiring convention and roughly twenty --bs-accordion-* variables to retheme. The same component in Tailwind is a <details name> group plus one class list: identical look and identical exclusive behaviour, with the JavaScript dependency deleted rather than ported.
One accordion, five codebases: a working native-<details> FAQ up top, and beneath it a pure-CSS tab viewer showing the same component in React, Vue 3, Svelte 5 and Astro. The thesis is stronger in Tailwind than it was in CSS — because the class list travels with the markup, the port really is just a data-mapping shell, with no stylesheet to move at all.
Speak your question and watch the FAQ filter: a microphone button feeds the Speech Recognition API into the same live filter as demo 18, with interim results streaming into the input as you talk and a pulsing listening ring. The part most voice demos skip is the whole point here — the mic only renders where the API exists, the typed filter is the baseline everyone gets, and every state change is announced.
FAQ
Frequently asked questions
How does the Tailwind FAQ accordion open without any JavaScript?
Two mechanisms cover every demo here, neither needs a framework. Demo 01 uses the checkbox hack: a visually hidden <input type="checkbox"> marked peer holds the open state, its <label> is the clickable question, and the answer panel reacts with peer-checked:grid-rows-[1fr]. Demo 02 uses the native <details>/<summary> element, which tracks its own open attribute with no markup tricks at all. Reach for <details> first — it is semantic, focusable and keyboard-operable out of the box. The peer approach only earns its keep when you need to style a state combination <details> cannot express, like a sibling panel reacting to a checkbox two elements away, or a header whose colour depends on the open state of a different question.
How do I make only one FAQ open at a time in Tailwind?
Give every <details> in the group the same name attribute and the browser enforces one-open-at-a-time for you — opening one closes its siblings, exactly like a radio group, with no sibling-closing script. Demo 03 does this; demo 04 deliberately omits name so panels stay independent and users can compare three answers side by side. The common trap: name only groups elements that share the exact same value, so a typo in one name silently drops that panel out of the group and it behaves as multi-open. Note support is recent — in older engines the attribute is ignored and every panel opens independently, which is a safe visual degradation but not the exclusive behaviour you designed. If you must guarantee single-open in every browser, fall back to the radio-input pattern with peer instead of relying on name.
Why won't my Tailwind accordion animate to height auto?
You cannot transition to height: auto, which is why a naive toggle snaps open instead of sliding. Demo 10 uses the modern fix: wrap the answer in a grid whose row is grid-template-rows: 0fr when collapsed and 1fr when open, then transition the row track — Tailwind writes this as grid-rows-[0fr] flipping to peer-checked:grid-rows-[1fr]. The inner panel must carry min-h-0 overflow-hidden or the content refuses to collapse below its intrinsic height and you see a permanent sliver of text at rest. The other option is animating max-height between 0 and a value larger than any answer, but that couples your timing to a guessed height and eases unevenly. The 0fr → 1fr grid measures the real content, so the motion stays honest whether the answer is one line or ten.
How do I rotate the FAQ chevron or morph a plus into a minus on open?
Rotate the icon element only, never the whole row. Demo 11 places a chevron inside the <summary> and gives it transition-transform plus a state-driven turn — under <details> that is group-open:rotate-180, under the peer checkbox it is peer-checked:rotate-180. Demo 12 morphs a plus into a minus by rotating both bars a half-turn together. The bug everyone hits: omitting transition-transform so the icon jumps instantly, or rotating a parent that also holds the label text so the whole question tilts. Keep the rotating scope to the glyph, give it shrink-0 so a long question cannot squash it, and mark it aria-hidden since it is decorative — the open state is already announced by the <summary> or <button> it lives inside, so a screen reader should not read the icon too.
Is a Tailwind details/summary FAQ accessible, or do I need full ARIA?
Native <details>/<summary> (demo 02) is accessible by default: the summary is a real button, reachable by Tab, toggled with Enter or Space, and its expanded state is announced. That covers most FAQs with no extra attributes. Demo 21 implements the full WAI-ARIA Authoring Practices accordion for when you need more — each question is a real <button> wrapped in a heading, carrying aria-expanded and aria-controls that points at its panel, with the panel pointing back via aria-labelledby. The difference that matters is keyboard navigation: the ARIA pattern adds Up/Down arrow movement between headers plus Home and End, which the native element does not provide. The checkbox-hack demos need the most care — a bare <label> is not tab-focusable, so you must wire the hidden input into the focus order or keyboard users cannot open a single panel.
How do I add FAQPage JSON-LD schema to the accordion?
Demo 22 mirrors the visible accordion with a FAQPage block inside a <script type="application/ld+json"> tag. Each visible question becomes one Question entry with an acceptedAnswer, and the rule people miss is fidelity: the structured answer must match what a user actually sees on the page — paraphrasing, or adding questions that are not visible, breaks the guidelines rather than gaming them. Keep the two in lockstep by generating both from one data array instead of hand-writing the script. One gotcha specific to this markup: any raw HTML tag left inside an answer string will close the surrounding <script> early and silently drop every entry after it, so escape your angle brackets or strip tags before serialising. The visible accordion works fine without the block; the JSON-LD only layers machine-readable structure on top of it.
When should I not use a CSS-only FAQ accordion?
Skip the pure-CSS patterns the moment the interaction outgrows what state selectors can express. Demo 18's live search, demo 19's expand-all / collapse-all, demo 25's voice input and any open-tracking analytics all need JavaScript — the peer and <details> tricks only toggle visibility; they cannot filter, bulk-control or report. Avoid the checkbox hack specifically when a native <details> would do the same job: it is more markup, less semantic, and easy to leave un-focusable. And do not force an accordion at all onto three short answers — collapsing content behind a click hides it from readers who would happily scan it and buries it from the browser's in-page find. Reach for the accordion when the list is long enough that scrolling past closed questions genuinely helps, default to <details>, and escalate to the ARIA build only when you need arrow-key navigation or a controlled single-open group everywhere.
How does the type-to-filter FAQ search work, and is voice search safe to rely on?
Demo 18 filters as you type by reading the input value and hiding every question whose text does not match — it searches both the question and the answer body, then auto-expands the surviving matches so a hit is visible, not merely present. Demo 25 feeds that same filter from the Speech Recognition API: a microphone button starts recognition and the transcript becomes the query. Two things to plan for. Speech recognition is not universally supported and needs a secure origin plus a microphone permission prompt, so feature-detect it and keep the text input as the fallback — never make voice the only way in. And when a filter empties the list, render a visible no results state; silently showing an empty panel reads as a broken page. Both features sit on top of the same underlying accordion, so the markup a user copies stays identical whether or not they wire up search.