08 / 25
All 25 in 25 Tailwind CSS FAQ Accordion
- 01Tailwind Peer-Checked FAQ Accordion with No JavaScript
- 02Tailwind Native Details/Summary FAQ with Custom Styled Icons
- 03Tailwind Exclusive Accordion — Only One FAQ Open at a Time
- 04Tailwind Multi-Open FAQ Accordion with a Live CSS Counter
- 05Tailwind CSS FAQ Accordion Template (Free, Copy-Paste)
- 06Tailwind Dark Mode FAQ Accordion with light-dark() and No .dark Class
- 07Tailwind Glassmorphism FAQ Accordion with Frosted Backdrop Blur
- 08Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
- 09Tailwind Neumorphic Soft-UI FAQ Accordion Cards
- 10Tailwind Animate Height Auto FAQ with grid-rows 0fr to 1fr
- 11Tailwind FAQ Chevron Rotate 180 Degrees on Toggle
- 12Tailwind Animated Plus to Minus Icon Morph FAQ Accordion
- 13Tailwind Spring Bounce FAQ Accordion with linear() Easing
- 14Tailwind Two-Column FAQ Accordion Grid with Independent Columns
- 15Tailwind Horizontal FAQ Accordion with Sideways Expanding Panels
- 16Tailwind Categorised FAQ Help Centre with a Sticky Sidebar Menu
- 17Tailwind Card-Style FAQ Panels with a Layered Shadow Elevation System
- 18Tailwind FAQ Accordion with a Live Search Bar Filter
- 19Tailwind Expand All and Collapse All FAQ Accordion Buttons
- 20Tailwind FAQ with a Still Have Questions Contact CTA Card
- 21Tailwind Accessible ARIA FAQ Accordion with Keyboard Navigation
- 22Tailwind FAQ with FAQPage JSON-LD Schema for Rich Snippets and AI Search
- 23Bootstrap 5 Accordion Rebuilt in Tailwind (and the JavaScript You Delete)
- 24Tailwind FAQ Component in React, Vue, Svelte and Astro (One Port Recipe)
- 25Tailwind FAQ with Voice Search Using the Speech Recognition API
Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
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.
Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49
Cruip · Affiliate link
The code
<section class="tfa-08 w-full min-h-svh font-tfa08-sans text-tfa08-ink">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa08-bg px-5 py-12">
<div class="grid w-[min(980px,100%)] items-center gap-8 @3xl:grid-cols-[minmax(0,5fr)_minmax(0,6fr)] @3xl:gap-16">
<figure class="flex aspect-[16/10] max-h-[340px] items-end bg-[linear-gradient(oklch(0.9_0.01_80/0.1),oklch(0.85_0.015_70/0.2)),url('https://images.unsplash.com/photo-1523381210434-271e8be1f52b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center @3xl:aspect-[4/5] @3xl:max-h-none">
<figcaption class="w-full bg-[linear-gradient(transparent,oklch(0.2_0.01_60/0.55))] px-4 py-3.5 text-[12px] uppercase tracking-[0.08em] text-white">Heavyweight organic tee — $48</figcaption>
</figure>
<div>
<h1 class="text-[clamp(22px,3.4vw,30px)] font-semibold tracking-[-0.02em]">Details & care</h1>
<div data-panel class="mt-5 border-t border-tfa08-line">
<details class="group border-b border-tfa08-line" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Shipping & delivery
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Free carbon-neutral shipping over $75, dispatched within 24 hours. US 2–4 business days, UK & EU 3–5, Australia 4–7. A tracked link lands in your inbox at dispatch.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Returns & exchanges
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">60 days, free, no questions. Start a return from your order email and drop the package at any carrier point — refunds land 3–5 days after scanning. Exchanges ship before your return even arrives.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Fabric & fit
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">230gsm organic cotton, garment-dyed and pre-shrunk. The fit is relaxed through the body with a ribbed collar that holds its shape — if you are between sizes, size down.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Care instructions
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Machine wash cold, inside out, with like colours. Hang dry — the dryer is where the garment-dye patina goes to die. Iron low, never on the print.</p>
</details>
</div>
<p class="mt-4 text-[11.5px] tracking-[0.04em] text-tfa08-mut">One hairline per item, one accent colour, zero boxes.</p>
</div>
</div>
</div>
</section><section class="tfa-08 w-full min-h-svh font-tfa08-sans text-tfa08-ink">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa08-bg px-5 py-12">
<div class="grid w-[min(980px,100%)] items-center gap-8 @3xl:grid-cols-[minmax(0,5fr)_minmax(0,6fr)] @3xl:gap-16">
<figure class="flex aspect-[16/10] max-h-[340px] items-end bg-[linear-gradient(oklch(0.9_0.01_80/0.1),oklch(0.85_0.015_70/0.2)),url('https://images.unsplash.com/photo-1523381210434-271e8be1f52b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center @3xl:aspect-[4/5] @3xl:max-h-none">
<figcaption class="w-full bg-[linear-gradient(transparent,oklch(0.2_0.01_60/0.55))] px-4 py-3.5 text-[12px] uppercase tracking-[0.08em] text-white">Heavyweight organic tee — $48</figcaption>
</figure>
<div>
<h1 class="text-[clamp(22px,3.4vw,30px)] font-semibold tracking-[-0.02em]">Details & care</h1>
<div data-panel class="mt-5 border-t border-tfa08-line">
<details class="group border-b border-tfa08-line" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Shipping & delivery
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Free carbon-neutral shipping over $75, dispatched within 24 hours. US 2–4 business days, UK & EU 3–5, Australia 4–7. A tracked link lands in your inbox at dispatch.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Returns & exchanges
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">60 days, free, no questions. Start a return from your order email and drop the package at any carrier point — refunds land 3–5 days after scanning. Exchanges ship before your return even arrives.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Fabric & fit
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">230gsm organic cotton, garment-dyed and pre-shrunk. The fit is relaxed through the body with a ribbed collar that holds its shape — if you are between sizes, size down.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Care instructions
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Machine wash cold, inside out, with like colours. Hang dry — the dryer is where the garment-dye patina goes to die. Iron low, never on the print.</p>
</details>
</div>
<p class="mt-4 text-[11.5px] tracking-[0.04em] text-tfa08-mut">One hairline per item, one accent colour, zero boxes.</p>
</div>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The named container and its width-based rule became
@containerplus@3xl:variants. The whole responsive block left the stylesheet, and the direction inverted to mobile-first, which is the better default here. - The em-dash marker is two pseudo-element hairlines with only
after:rotating, sogroup-open:after:rotate-0is the entire morph. No SVG, no icon font, one element. group-[&:not([open])]:(v4'snot-*variant composed withgroup-*) replaces the original's:not([open])descendant selector for the 4px settle — a rare case where the utility spelling is shorter than the selector.- UI upgrade from the CSS original: the accent moved
oklch(0.55 0.12 40)→0.52(about 4.2:1 → 4.9:1 on the bone ground), and the label row is uppercase at a full 14px, legible at arm's length on a phone. - UI upgrade: the photo states its aspect ratio per breakpoint (16/10 narrow, 4/5 wide) instead of overriding it inside the container query, so nothing shifts as the container crosses the breakpoint.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-minimalist-ecommerce-faq-accordion/
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.
## HTML
```html
<section class="tfa-08 w-full min-h-svh font-tfa08-sans text-tfa08-ink">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa08-bg px-5 py-12">
<div class="grid w-[min(980px,100%)] items-center gap-8 @3xl:grid-cols-[minmax(0,5fr)_minmax(0,6fr)] @3xl:gap-16">
<figure class="flex aspect-[16/10] max-h-[340px] items-end bg-[linear-gradient(oklch(0.9_0.01_80/0.1),oklch(0.85_0.015_70/0.2)),url('https://images.unsplash.com/photo-1523381210434-271e8be1f52b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center @3xl:aspect-[4/5] @3xl:max-h-none">
<figcaption class="w-full bg-[linear-gradient(transparent,oklch(0.2_0.01_60/0.55))] px-4 py-3.5 text-[12px] uppercase tracking-[0.08em] text-white">Heavyweight organic tee — $48</figcaption>
</figure>
<div>
<h1 class="text-[clamp(22px,3.4vw,30px)] font-semibold tracking-[-0.02em]">Details & care</h1>
<div data-panel class="mt-5 border-t border-tfa08-line">
<details class="group border-b border-tfa08-line" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Shipping & delivery
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Free carbon-neutral shipping over $75, dispatched within 24 hours. US 2–4 business days, UK & EU 3–5, Australia 4–7. A tracked link lands in your inbox at dispatch.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Returns & exchanges
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">60 days, free, no questions. Start a return from your order email and drop the package at any carrier point — refunds land 3–5 days after scanning. Exchanges ship before your return even arrives.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Fabric & fit
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">230gsm organic cotton, garment-dyed and pre-shrunk. The fit is relaxed through the body with a ribbed collar that holds its shape — if you are between sizes, size down.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Care instructions
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Machine wash cold, inside out, with like colours. Hang dry — the dryer is where the garment-dye patina goes to die. Iron low, never on the print.</p>
</details>
</div>
<p class="mt-4 text-[11.5px] tracking-[0.04em] text-tfa08-mut">One hairline per item, one accent colour, zero boxes.</p>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-minimalist-ecommerce-faq-accordion/
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.
## HTML
```html
<section class="tfa-08 w-full min-h-svh font-tfa08-sans text-tfa08-ink">
<div class="@container grid min-h-svh w-full place-items-center bg-tfa08-bg px-5 py-12">
<div class="grid w-[min(980px,100%)] items-center gap-8 @3xl:grid-cols-[minmax(0,5fr)_minmax(0,6fr)] @3xl:gap-16">
<figure class="flex aspect-[16/10] max-h-[340px] items-end bg-[linear-gradient(oklch(0.9_0.01_80/0.1),oklch(0.85_0.015_70/0.2)),url('https://images.unsplash.com/photo-1523381210434-271e8be1f52b?q=80&w=1200&auto=format&fit=crop')] bg-cover bg-center @3xl:aspect-[4/5] @3xl:max-h-none">
<figcaption class="w-full bg-[linear-gradient(transparent,oklch(0.2_0.01_60/0.55))] px-4 py-3.5 text-[12px] uppercase tracking-[0.08em] text-white">Heavyweight organic tee — $48</figcaption>
</figure>
<div>
<h1 class="text-[clamp(22px,3.4vw,30px)] font-semibold tracking-[-0.02em]">Details & care</h1>
<div data-panel class="mt-5 border-t border-tfa08-line">
<details class="group border-b border-tfa08-line" open>
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Shipping & delivery
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Free carbon-neutral shipping over $75, dispatched within 24 hours. US 2–4 business days, UK & EU 3–5, Australia 4–7. A tracked link lands in your inbox at dispatch.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Returns & exchanges
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">60 days, free, no questions. Start a return from your order email and drop the package at any carrier point — refunds land 3–5 days after scanning. Exchanges ship before your return even arrives.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Fabric & fit
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">230gsm organic cotton, garment-dyed and pre-shrunk. The fit is relaxed through the body with a ribbed collar that holds its shape — if you are between sizes, size down.</p>
</details>
<details class="group border-b border-tfa08-line">
<summary class="flex min-h-11 cursor-pointer list-none items-center justify-between gap-4 px-0.5 py-[22px] text-[14px] font-semibold uppercase tracking-[0.06em] transition-colors duration-200 hover:text-tfa08-acc focus-visible:outline-[1.5px] focus-visible:outline-offset-4 focus-visible:outline-tfa08-acc [&::-webkit-details-marker]:hidden">Care instructions
<i aria-hidden="true" class="relative size-3.5 shrink-0 before:absolute before:inset-0 before:m-auto before:h-px before:w-3.5 before:bg-current after:absolute after:inset-0 after:m-auto after:h-px after:w-3.5 after:rotate-90 after:bg-current after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] group-open:after:rotate-0 motion-reduce:after:transition-none"></i>
</summary>
<p class="max-w-[52ch] px-0.5 pb-[22px] text-[13.5px] leading-[1.8] text-tfa08-mut transition-[translate,opacity] duration-350 group-[&:not([open])]:translate-y-1">Machine wash cold, inside out, with like colours. Hang dry — the dryer is where the garment-dye patina goes to die. Iron low, never on the print.</p>
</details>
</div>
<p class="mt-4 text-[11.5px] tracking-[0.04em] text-tfa08-mut">One hairline per item, one accent colour, zero boxes.</p>
</div>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tfa08-bg: #fdfdfb;
--color-tfa08-bg: oklch(0.99 0.004 90);
--color-tfa08-ink: #3b332c;
--color-tfa08-ink: oklch(0.24 0.012 60);
--color-tfa08-mut: #6d645c;
--color-tfa08-mut: oklch(0.45 0.015 60);
--color-tfa08-line: #e5e1d9;
--color-tfa08-line: oklch(0.9 0.008 80);
--color-tfa08-acc: #9d5a2f;
--color-tfa08-acc: oklch(0.52 0.12 40);
--font-tfa08-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
}
.tfa-08 {
width: 100%;
min-height: 100svh;
}
.tfa-08 [data-panel] {
interpolate-size: allow-keywords;
}
@supports (interpolate-size: allow-keywords) {
.tfa-08 details::details-content {
height: 0;
overflow: clip;
opacity: 0;
transition: height .4s cubic-bezier(.4,0,.2,1), opacity .3s, content-visibility .4s allow-discrete;
}
.tfa-08 details[open]::details-content {
height: auto;
opacity: 1;
}
}
@media (prefers-reduced-motion: reduce) {
.tfa-08 details::details-content {
transition-duration: 1ms;
}
}
```How this works
Restraint is the technique. One hairline between items, never a bordered box: a single border-t on the list and one border-b per <details>. That is the whole chrome.
The marker is typographic rather than iconic: two 14×1px hairlines, one rotated, so opening a panel morphs a plus into a single em dash. At this level of restraint motion carries the personality — group-[&:not([open])]:translate-y-1 slides the answer up 4px as it fades in, which reads as considered without adding a visual element.
Container queries are the headline. The CSS version needed a named container and a media-query-shaped rule:
.stage{ container: cfa08/inline-size }
@container cfa08 (width < 720px){ .cols{ grid-template-columns:1fr } }In v4 that is @container on the parent and @3xl: variants on the child — the query lives on the element that responds to it, and the CSS block disappears entirely. Note the inversion: the CSS version wrote the narrow case as an override, the utility version states the wide case as an enhancement.
Placement note, because this is a conversion component: shipping-cost and returns answers near the buy button measurably reduce cart abandonment. This is not documentation; it is objection handling.
Make it yours
- Accent: the accent token is used twice (hover ink, focus ring). Swap once.
- Photo: replace the background-image utility; the
aspect-[4/5]box prevents layout shift while it loads. - Denser: summary
py-[22px]→py-3.5turns the FAQ into a spec-sheet accordion. - Reflow sooner:
@3xl:→@4xl:— container breakpoints use the same scale as screens.
Gotchas — read before shipping
- Resist
rounded-*here: rounded corners plus hairline dividers is two design languages fighting. Pick boxes (demo 17) or lines, not both. - 1px hairlines double on high-DPI screens if you use pure greys — a low-chroma oklch token reads as one line at 1x and 2x.
- Minimal is not low contrast: the muted ink here is oklch 0.45, safely over 4.5:1. Most minimal palettes fail WCAG at the usual mid-grey.
@containermust be on an ANCESTOR of the element carrying container variants — a container cannot query itself.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 129+ | not yet | not yet | 129+ |
Floor set by oklch(), @container, interpolate-size as this demo is written. The core technique itself goes back further — Chrome 111+.
Container queries are Chrome 105 / Safari 16 / Firefox 110, comfortably inside Tailwind v4's own floor. Structure is universal <details>; the animated panel enhances progressively.