25 Tailwind CSS FAQ Accordion
12 / 25

All 25 in 25 Tailwind CSS FAQ Accordion

  1. 01Tailwind Peer-Checked FAQ Accordion with No JavaScript
  2. 02Tailwind Native Details/Summary FAQ with Custom Styled Icons
  3. 03Tailwind Exclusive Accordion — Only One FAQ Open at a Time
  4. 04Tailwind Multi-Open FAQ Accordion with a Live CSS Counter
  5. 05Tailwind CSS FAQ Accordion Template (Free, Copy-Paste)
  6. 06Tailwind Dark Mode FAQ Accordion with light-dark() and No .dark Class
  7. 07Tailwind Glassmorphism FAQ Accordion with Frosted Backdrop Blur
  8. 08Tailwind Minimalist E-Commerce FAQ Accordion for Product Pages
  9. 09Tailwind Neumorphic Soft-UI FAQ Accordion Cards
  10. 10Tailwind Animate Height Auto FAQ with grid-rows 0fr to 1fr
  11. 11Tailwind FAQ Chevron Rotate 180 Degrees on Toggle
  12. 12Tailwind Animated Plus to Minus Icon Morph FAQ Accordion
  13. 13Tailwind Spring Bounce FAQ Accordion with linear() Easing
  14. 14Tailwind Two-Column FAQ Accordion Grid with Independent Columns
  15. 15Tailwind Horizontal FAQ Accordion with Sideways Expanding Panels
  16. 16Tailwind Categorised FAQ Help Centre with a Sticky Sidebar Menu
  17. 17Tailwind Card-Style FAQ Panels with a Layered Shadow Elevation System
  18. 18Tailwind FAQ Accordion with a Live Search Bar Filter
  19. 19Tailwind Expand All and Collapse All FAQ Accordion Buttons
  20. 20Tailwind FAQ with a Still Have Questions Contact CTA Card
  21. 21Tailwind Accessible ARIA FAQ Accordion with Keyboard Navigation
  22. 22Tailwind FAQ with FAQPage JSON-LD Schema for Rich Snippets and AI Search
  23. 23Bootstrap 5 Accordion Rebuilt in Tailwind (and the JavaScript You Delete)
  24. 24Tailwind FAQ Component in React, Vue, Svelte and Astro (One Port Recipe)
  25. 25Tailwind FAQ with Voice Search Using the Speech Recognition API
Pure TailwindMIT licensed

Tailwind Animated Plus to Minus Icon Morph FAQ Accordion

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.

Live Demo
Plain CSSTailwind v4
Try it

Complete Tailwind CSS landing page templates in HTML, React, Next.js and Vue · from $49

Cruip · Affiliate link

Browse Cruip templates

The code

<section class="tfa-12 w-full min-h-svh grid place-items-center bg-tfa12-bg font-tfa12-sans text-tfa12-ink px-5 py-12 bg-[radial-gradient(900px_600px_at_0%_0%,var(--color-tfa12-glow),transparent_55%)]">
  <div class="w-[min(660px,100%)]">
    <header>
      <h1 class="text-[clamp(28px,5vw,40px)] font-extrabold leading-[1.08] tracking-[-0.025em]">Studio FAQ</h1>
      <p class="mt-3 max-w-[54ch] text-[15px] leading-relaxed text-tfa12-mut">Watch the plus twist itself into a minus — both bars rotate, one collapses along its length.</p>
    </header>

    <div class="mt-8 flex flex-col gap-2.5">
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q1" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
        <label for="tfa12-q1" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Do you take on freelance projects?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Selectively — two or three a quarter, usually brand systems or product design sprints. Send a short brief with timeline and budget range; we reply within two business days either way.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q2" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q2" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">What does a typical engagement cost?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Sprints start at $12k for two weeks; full brand systems run $40–90k depending on scope. Fixed-price after discovery — we do not bill hours, so a slow Tuesday is our problem, not yours.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q3" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q3" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Can we hire you to work inside our team?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Yes — embedded engagements of 1–3 months, joining your standups and shipping in your codebase or design system. It is the fastest way to transfer taste, not just deliverables.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q4" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q4" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Who owns the work?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">You do, fully, on final payment — source files, fonts we licensed for you, the lot. We keep the right to show the work in our portfolio unless the contract says otherwise.</p></div>
        </div>
      </div>
    </div>

    <p class="mt-6 text-[12.5px] text-tfa12-mut">The morph: both bars to 180°, the vertical one to <code class="rounded bg-tfa12-tint px-1.5 py-0.5 font-tfa12-mono text-[0.88em] text-tfa12-acc">scale-x-0</code>, on one overshoot curve.</p>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tfa12-bg: #1e2620;
  --color-tfa12-bg: oklch(0.24 0.03 145);
  --color-tfa12-panel: #26302a;
  --color-tfa12-panel: oklch(0.28 0.035 148);
  --color-tfa12-glow: #2a3a26;
  --color-tfa12-glow: oklch(0.3 0.06 130 / 0.6);
  --color-tfa12-ink: #f2f7f0;
  --color-tfa12-ink: oklch(0.96 0.01 140);
  --color-tfa12-mut: #bcc7b9;
  --color-tfa12-mut: oklch(0.81 0.022 142);
  --color-tfa12-edge: #3b473c;
  --color-tfa12-edge: oklch(0.37 0.04 146);
  --color-tfa12-accedge: #6c9a55;
  --color-tfa12-accedge: oklch(0.62 0.11 130);
  --color-tfa12-tint: #30412b;
  --color-tfa12-tint: oklch(0.33 0.055 130);
  --color-tfa12-acc: #b9ec7f;
  --color-tfa12-acc: oklch(0.87 0.16 130);
  --font-tfa12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa12-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tfa-12 {
  width: 100%;
  min-height: 100svh;
}

Setup — do this once per project

Skip this if your project already runs Tailwind v4.

1Load Tailwind
<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.

2Add the stylesheetRequiredthe @theme block is what makes the custom utilities exist
@import "tailwindcss";

@theme {
  --color-tfa12-bg: #1e2620;
  --color-tfa12-bg: oklch(0.24 0.03 145);
  --color-tfa12-panel: #26302a;
  --color-tfa12-panel: oklch(0.28 0.035 148);
  --color-tfa12-glow: #2a3a26;
  --color-tfa12-glow: oklch(0.3 0.06 130 / 0.6);
  --color-tfa12-ink: #f2f7f0;
  --color-tfa12-ink: oklch(0.96 0.01 140);
  --color-tfa12-mut: #bcc7b9;
  --color-tfa12-mut: oklch(0.81 0.022 142);
  --color-tfa12-edge: #3b473c;
  --color-tfa12-edge: oklch(0.37 0.04 146);
  --color-tfa12-accedge: #6c9a55;
  --color-tfa12-accedge: oklch(0.62 0.11 130);
  --color-tfa12-tint: #30412b;
  --color-tfa12-tint: oklch(0.33 0.055 130);
  --color-tfa12-acc: #b9ec7f;
  --color-tfa12-acc: oklch(0.87 0.16 130);
  --font-tfa12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa12-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tfa-12 {
  width: 100%;
  min-height: 100svh;
}
3Fonts used by this demooptional — skip if you have your own type stack
<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;700;800&family=JetBrains+Mono:wght@400;500&display=swap">

What changed in the port

Which parts became utilities, which stayed CSS, and why.

  • Another tokens-only stylesheet: an icon drawn from two pseudo-elements, animated on state, is fully expressible in variants — peer-checked:after:scale-x-0 is three levels of composition in one class and needs no CSS at all.
  • group/row is the fix for a collision the CSS version never had: the label is simultaneously the peer-follower and the hover group. Naming the group makes both relationships explicit, and it is the habit to keep once a component has more than one group.
  • scale-x-0 replaces the original's scale:0 1 shorthand. Same result, and the axis is now named in the class rather than implied by argument order.
  • UI upgrade from the CSS original: muted copy oklch(0.72) → 0.81 on a lighter panel (0.25 → 0.28), taking answer text from about 4.1:1 to 5.6:1.
  • UI upgrade: the chip swells on hover anywhere in the row rather than only over the icon, and reduced motion now keeps the colour transition — the original disabled every transition, including the one that confirmed the toggle.
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
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 Animated Plus to Minus Icon Morph FAQ Accordion
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-plus-to-minus-icon-morph-faq/

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.
## HTML
```html
<section class="tfa-12 w-full min-h-svh grid place-items-center bg-tfa12-bg font-tfa12-sans text-tfa12-ink px-5 py-12 bg-[radial-gradient(900px_600px_at_0%_0%,var(--color-tfa12-glow),transparent_55%)]">
  <div class="w-[min(660px,100%)]">
    <header>
      <h1 class="text-[clamp(28px,5vw,40px)] font-extrabold leading-[1.08] tracking-[-0.025em]">Studio FAQ</h1>
      <p class="mt-3 max-w-[54ch] text-[15px] leading-relaxed text-tfa12-mut">Watch the plus twist itself into a minus — both bars rotate, one collapses along its length.</p>
    </header>

    <div class="mt-8 flex flex-col gap-2.5">
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q1" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
        <label for="tfa12-q1" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Do you take on freelance projects?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Selectively — two or three a quarter, usually brand systems or product design sprints. Send a short brief with timeline and budget range; we reply within two business days either way.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q2" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q2" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">What does a typical engagement cost?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Sprints start at $12k for two weeks; full brand systems run $40–90k depending on scope. Fixed-price after discovery — we do not bill hours, so a slow Tuesday is our problem, not yours.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q3" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q3" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Can we hire you to work inside our team?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">Yes — embedded engagements of 1–3 months, joining your standups and shipping in your codebase or design system. It is the fastest way to transfer taste, not just deliverables.</p></div>
        </div>
      </div>
      <div class="relative overflow-hidden rounded-2xl border border-tfa12-edge bg-tfa12-panel transition-[border-color,box-shadow] duration-300 has-checked:border-tfa12-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.85_0.17_130/0.45)]">
        <input id="tfa12-q4" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
        <label for="tfa12-q4" class="group/row flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15.5px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa12-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa12-acc">Who owns the work?
          <i aria-hidden="true" class="relative grid size-[26px] shrink-0 place-items-center rounded-[9px] bg-tfa12-tint text-tfa12-mut transition-[scale,color] duration-250 group-hover/row:scale-110 group-hover/row:text-tfa12-acc peer-checked:text-tfa12-acc before:absolute before:h-0.5 before:w-3.5 before:rounded-full before:bg-current before:transition-[rotate,scale] before:duration-450 before:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] after:absolute after:h-0.5 after:w-3.5 after:rounded-full after:bg-current after:rotate-90 after:transition-[rotate,scale] after:duration-450 after:ease-[cubic-bezier(0.5,-0.3,0.3,1.3)] peer-checked:before:rotate-180 peer-checked:after:rotate-180 peer-checked:after:scale-x-0 motion-reduce:before:transition-none motion-reduce:after:transition-none motion-reduce:transition-colors"></i>
        </label>
        <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-450 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none">
          <div class="min-h-0 overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa12-mut">You do, fully, on final payment — source files, fonts we licensed for you, the lot. We keep the right to show the work in our portfolio unless the contract says otherwise.</p></div>
        </div>
      </div>
    </div>

    <p class="mt-6 text-[12.5px] text-tfa12-mut">The morph: both bars to 180°, the vertical one to <code class="rounded bg-tfa12-tint px-1.5 py-0.5 font-tfa12-mono text-[0.88em] text-tfa12-acc">scale-x-0</code>, on one overshoot curve.</p>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tfa12-bg: #1e2620;
  --color-tfa12-bg: oklch(0.24 0.03 145);
  --color-tfa12-panel: #26302a;
  --color-tfa12-panel: oklch(0.28 0.035 148);
  --color-tfa12-glow: #2a3a26;
  --color-tfa12-glow: oklch(0.3 0.06 130 / 0.6);
  --color-tfa12-ink: #f2f7f0;
  --color-tfa12-ink: oklch(0.96 0.01 140);
  --color-tfa12-mut: #bcc7b9;
  --color-tfa12-mut: oklch(0.81 0.022 142);
  --color-tfa12-edge: #3b473c;
  --color-tfa12-edge: oklch(0.37 0.04 146);
  --color-tfa12-accedge: #6c9a55;
  --color-tfa12-accedge: oklch(0.62 0.11 130);
  --color-tfa12-tint: #30412b;
  --color-tfa12-tint: oklch(0.33 0.055 130);
  --color-tfa12-acc: #b9ec7f;
  --color-tfa12-acc: oklch(0.87 0.16 130);
  --font-tfa12-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa12-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tfa-12 {
  width: 100%;
  min-height: 100svh;
}
```

How this works

Two bars, one box, all pseudo-elements. The chip is relative grid size-[26px] place-items-center; each bar is a 14×2px rounded before:/after: with the second pre-rotated 90°. Both inherit bg-current, so one colour utility on the chip recolours the glyph.

The choreography. The naive morph fades the vertical bar out — functional, forgettable. Here both bars travel a half-turn while the vertical one goes scale-x-0, shrinking along its own length rather than fading, so mid-animation the glyph passes through a genuine cross-ish shape before settling as a minus. The overshoot curve (a negative and an over-one control value) twists a few degrees past and recoils: physical, toy-like, free.

Named groups are the port's real lesson. The chip must react to hover on the whole row, but the row is also the peer-following label. group/row on the label plus group-hover/row: on the chip keeps the two relationships from colliding — unnamed groups would be ambiguous the moment a second group appears.

Make it yours

  • Calm version: swap the overshoot curve for the standard ease and delete after:scale-x-0 — the classic quiet morph.
  • Close-affordance variant: rotate the bars to 45°/135° on open instead, and the plus becomes a cross — right for accordions that behave like dismissible drawers.
  • Chip styling: drop bg-tfa12-tint and the radius for naked bars on minimal designs (demo 08).
  • Size: keep bar thickness at or above 2px, or sub-pixel rendering shimmers during rotation.

Gotchas — read before shipping

  • Use rotate-* and scale-x-* (individual properties), never an arbitrary transform: — the two bars share timing but differ in end state, and composed transforms overwrite each other.
  • The bars centre only because the chip is relative and the bars are absolutely positioned inside a grid centre — the classic invisible-icon bug is a missing relative.
  • The overshoot curve looks broken past about 600ms. Keep it in the 350–500ms range.
  • motion-reduce: must kill the twist but keep the colour change: the bar count still changes, so nothing functional is lost.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

Individual rotate/scale properties are 2022-settled; pseudo-element variants compile to ordinary ::before/::after rules. The floor is Tailwind v4's generated sheet.

Techniques used in this demo

Utilitiesfirst-class utility or variant

Search CodeFronts

Loading…