25 Tailwind CSS FAQ Accordion
04 / 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
Tailwind v4MIT licensed

Tailwind Multi-Open FAQ Accordion with a Live CSS Counter

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.

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-04 w-full min-h-svh grid place-items-center bg-tfa04-bg font-tfa04-sans text-tfa04-ink px-5 py-12 bg-[radial-gradient(900px_520px_at_12%_0%,var(--color-tfa04-glow),transparent_62%)]">
  <div class="w-[min(700px,100%)]">
    <header>
      <h1 class="text-[clamp(28px,5vw,40px)] font-extrabold leading-[1.08] tracking-[-0.025em]">Compare answers freely</h1>
      <p class="mt-3 max-w-[54ch] text-[15px] leading-relaxed text-tfa04-mut">Every panel stays open independently — read across, not one at a time. The counter below the heading is pure CSS.</p>
    </header>

    <div class="mt-7 flex flex-col">
      <div class="flex flex-col gap-2.5 [counter-reset:tfa04open]">
        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q1" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
          <label for="tfa04-q1" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">What is the difference between Starter and Pro?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Starter covers one workspace with core analytics. Pro adds unlimited workspaces, funnels, cohort reports and priority support — most teams upgrade when they hit three projects.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q2" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
          <label for="tfa04-q2" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Which plan do agencies usually pick?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Agencies almost always run Pro with the client-billing add-on: each client becomes a workspace with its own invoice line, and you can hand off ownership when an engagement ends.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q3" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q3" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Can I mix plans across one team?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">No — a workspace has one plan for everyone in it. You can run different plans on different workspaces under the same organisation and consolidate the billing.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q4" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q4" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Is there a nonprofit or education discount?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Registered nonprofits and accredited educators get 50% off Pro, verified once a year. Student projects are free on Starter with a .edu / .ac address.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q5" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q5" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">What happens to my data if I downgrade?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Nothing is deleted. Reports beyond the Starter limits freeze read-only, and re-upgrading unfreezes them instantly with full history intact.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q6" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q6" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Do you have a public roadmap?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Yes — roadmap.example.com shows what is planned, building and shipped. Every feature request you upvote notifies you on release.</p></div></div>
        </div>
      </div>

      <div class="order-first mb-3 flex items-baseline gap-2.5">
        <span aria-hidden="true" class="rounded-full bg-tfa04-tint px-3 py-1.5 font-tfa04-mono text-[12px] font-bold text-tfa04-acc after:content-[counter(tfa04open)_'_of_6_open']"></span>
        <span class="text-[11.5px] tracking-[0.04em] text-tfa04-mut">counted by CSS, not JavaScript</span>
      </div>
    </div>

    <p class="mt-6 text-[12.5px] text-tfa04-mut">Pattern note: multi-open beats only-one-open when users compare answers.</p>
  </div>
</section>
@import "tailwindcss";

@theme {
  --color-tfa04-bg: #201c2b;
  --color-tfa04-bg: oklch(0.22 0.025 300);
  --color-tfa04-panel: #292335;
  --color-tfa04-panel: oklch(0.26 0.028 300);
  --color-tfa04-glow: #3d2440;
  --color-tfa04-glow: oklch(0.32 0.07 330 / 0.5);
  --color-tfa04-ink: #f5f2f7;
  --color-tfa04-ink: oklch(0.97 0.006 300);
  --color-tfa04-mut: #bdb4c6;
  --color-tfa04-mut: oklch(0.8 0.016 300);
  --color-tfa04-edge: #3e3650;
  --color-tfa04-edge: oklch(0.36 0.03 300);
  --color-tfa04-accedge: #a4649b;
  --color-tfa04-accedge: oklch(0.62 0.1 330);
  --color-tfa04-tint: #3a2739;
  --color-tfa04-tint: oklch(0.3 0.05 330);
  --color-tfa04-acc: #f0a8d8;
  --color-tfa04-acc: oklch(0.83 0.13 330);
  --font-tfa04-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa04-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tfa-04 {
  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-tfa04-bg: #201c2b;
  --color-tfa04-bg: oklch(0.22 0.025 300);
  --color-tfa04-panel: #292335;
  --color-tfa04-panel: oklch(0.26 0.028 300);
  --color-tfa04-glow: #3d2440;
  --color-tfa04-glow: oklch(0.32 0.07 330 / 0.5);
  --color-tfa04-ink: #f5f2f7;
  --color-tfa04-ink: oklch(0.97 0.006 300);
  --color-tfa04-mut: #bdb4c6;
  --color-tfa04-mut: oklch(0.8 0.016 300);
  --color-tfa04-edge: #3e3650;
  --color-tfa04-edge: oklch(0.36 0.03 300);
  --color-tfa04-accedge: #a4649b;
  --color-tfa04-accedge: oklch(0.62 0.1 330);
  --color-tfa04-tint: #3a2739;
  --color-tfa04-tint: oklch(0.3 0.05 330);
  --color-tfa04-acc: #f0a8d8;
  --color-tfa04-acc: oklch(0.83 0.13 330);
  --font-tfa04-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa04-mono: 'JetBrains Mono', ui-monospace, monospace;
}

.tfa-04 {
  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;600&display=swap">

What changed in the port

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

  • .item:has(:checked){counter-increment:cfa04open} becomes has-checked:[counter-increment:tfa04open] — a variant plus an arbitrary property, and the clearest example in this collection of why the escape hatch exists. Counters are not design-scale values, so no utility should exist for them.
  • content:counter(cfa04open) " of 6 open" ports as after:content-[counter(tfa04open)_'_of_6_open']: the underscore escape carries the multi-value content list through intact, quotes and all.
  • The document-order constraint on counters is unchanged by the port — only the reordering spelling changed, from order:-1 to order-first.
  • UI upgrade from the CSS original: muted copy went oklch(0.68) → 0.8 (3.4:1 → 5.1:1 on the plum panel) and the accent chip got a solid tinted ground instead of a 12% color-mix, which was under 3:1 at 12px.
  • UI upgrade: open items now lift with a magenta-tinted shadow, so "3 of 6 open" is legible from the panel shapes alone rather than only from the chip.
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 Multi-Open FAQ Accordion with a Live CSS Counter
Source: https://codefronts.com/snippets/tailwind-css-faq-accordion/tailwind-multi-open-faq-accordion-css-counter/

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.
## HTML
```html
<section class="tfa-04 w-full min-h-svh grid place-items-center bg-tfa04-bg font-tfa04-sans text-tfa04-ink px-5 py-12 bg-[radial-gradient(900px_520px_at_12%_0%,var(--color-tfa04-glow),transparent_62%)]">
  <div class="w-[min(700px,100%)]">
    <header>
      <h1 class="text-[clamp(28px,5vw,40px)] font-extrabold leading-[1.08] tracking-[-0.025em]">Compare answers freely</h1>
      <p class="mt-3 max-w-[54ch] text-[15px] leading-relaxed text-tfa04-mut">Every panel stays open independently — read across, not one at a time. The counter below the heading is pure CSS.</p>
    </header>

    <div class="mt-7 flex flex-col">
      <div class="flex flex-col gap-2.5 [counter-reset:tfa04open]">
        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q1" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
          <label for="tfa04-q1" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">What is the difference between Starter and Pro?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Starter covers one workspace with core analytics. Pro adds unlimited workspaces, funnels, cohort reports and priority support — most teams upgrade when they hit three projects.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q2" type="checkbox" class="peer absolute opacity-0 pointer-events-none" checked>
          <label for="tfa04-q2" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Which plan do agencies usually pick?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Agencies almost always run Pro with the client-billing add-on: each client becomes a workspace with its own invoice line, and you can hand off ownership when an engagement ends.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q3" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q3" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Can I mix plans across one team?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">No — a workspace has one plan for everyone in it. You can run different plans on different workspaces under the same organisation and consolidate the billing.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q4" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q4" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Is there a nonprofit or education discount?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Registered nonprofits and accredited educators get 50% off Pro, verified once a year. Student projects are free on Starter with a .edu / .ac address.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q5" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q5" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">What happens to my data if I downgrade?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Nothing is deleted. Reports beyond the Starter limits freeze read-only, and re-upgrading unfreezes them instantly with full history intact.</p></div></div>
        </div>

        <div class="relative overflow-hidden rounded-2xl border border-tfa04-edge bg-tfa04-panel transition-[border-color,box-shadow] duration-300 has-checked:[counter-increment:tfa04open] has-checked:border-tfa04-accedge has-checked:shadow-[0_16px_38px_-24px_oklch(0.7_0.16_330/0.5)]">
          <input id="tfa04-q6" type="checkbox" class="peer absolute opacity-0 pointer-events-none">
          <label for="tfa04-q6" class="flex min-h-11 cursor-pointer select-none items-center justify-between gap-4 rounded-2xl px-5 py-4 text-[15px] font-semibold tracking-[-0.01em] transition-colors duration-200 hover:text-tfa04-acc peer-focus-visible:outline-2 peer-focus-visible:-outline-offset-2 peer-focus-visible:outline-tfa04-acc">Do you have a public roadmap?
            <i aria-hidden="true" class="relative grid size-6 shrink-0 place-items-center before:absolute before:h-0.5 before:w-3 before:rounded-full before:bg-tfa04-acc before:transition-transform before:duration-400 before:ease-[cubic-bezier(0.4,0,0.2,1)] after:absolute after:h-0.5 after:w-3 after:rounded-full after:bg-tfa04-acc after:rotate-90 after:transition-transform after:duration-400 after:ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:before:-rotate-180 peer-checked:after:rotate-0 motion-reduce:before:transition-none motion-reduce:after:transition-none"></i>
          </label>
          <div class="grid grid-rows-[0fr] transition-[grid-template-rows] duration-400 ease-[cubic-bezier(0.4,0,0.2,1)] peer-checked:grid-rows-[1fr] motion-reduce:transition-none"><div class="overflow-hidden"><p class="max-w-[60ch] px-5 pb-4 text-[14px] leading-[1.7] text-tfa04-mut">Yes — roadmap.example.com shows what is planned, building and shipped. Every feature request you upvote notifies you on release.</p></div></div>
        </div>
      </div>

      <div class="order-first mb-3 flex items-baseline gap-2.5">
        <span aria-hidden="true" class="rounded-full bg-tfa04-tint px-3 py-1.5 font-tfa04-mono text-[12px] font-bold text-tfa04-acc after:content-[counter(tfa04open)_'_of_6_open']"></span>
        <span class="text-[11.5px] tracking-[0.04em] text-tfa04-mut">counted by CSS, not JavaScript</span>
      </div>
    </div>

    <p class="mt-6 text-[12.5px] text-tfa04-mut">Pattern note: multi-open beats only-one-open when users compare answers.</p>
  </div>
</section>
```
## CSS
```css
@import "tailwindcss";

@theme {
  --color-tfa04-bg: #201c2b;
  --color-tfa04-bg: oklch(0.22 0.025 300);
  --color-tfa04-panel: #292335;
  --color-tfa04-panel: oklch(0.26 0.028 300);
  --color-tfa04-glow: #3d2440;
  --color-tfa04-glow: oklch(0.32 0.07 330 / 0.5);
  --color-tfa04-ink: #f5f2f7;
  --color-tfa04-ink: oklch(0.97 0.006 300);
  --color-tfa04-mut: #bdb4c6;
  --color-tfa04-mut: oklch(0.8 0.016 300);
  --color-tfa04-edge: #3e3650;
  --color-tfa04-edge: oklch(0.36 0.03 300);
  --color-tfa04-accedge: #a4649b;
  --color-tfa04-accedge: oklch(0.62 0.1 330);
  --color-tfa04-tint: #3a2739;
  --color-tfa04-tint: oklch(0.3 0.05 330);
  --color-tfa04-acc: #f0a8d8;
  --color-tfa04-acc: oklch(0.83 0.13 330);
  --font-tfa04-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
  --font-tfa04-mono: 'JetBrains Mono', ui-monospace, monospace;
}

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

How this works

Multi-open needs no code at all. Each item's checkbox is independent, so nothing closes anything; the interesting part is the readout. CSS counters can count selector matches, and has-checked: lets an item increment only when its hidden checkbox is checked:

<div class="[counter-reset:tfa04open]">
  <div class="has-checked:[counter-increment:tfa04open]">…</div>
</div>
<span class="after:content-[counter(tfa04open)]"></span>

The document-order constraint survives the port. An element can only display counters incremented by elements before it, which is why the chip sits after the list in the markup and is pulled up visually — here with order-first on a flex column rather than the original's order:-1. Utilities changed the spelling, not the rule.

Where arbitrary properties are correct. counter-reset and counter-increment are not design-scale values, so Tailwind ships no utilities and should not; [counter-increment:tfa04open] is the idiomatic answer, and namespacing the counter name per demo is what lets all 25 share a page.

Pattern note: multi-open beats exclusive when users compare answers; it also grows tall fast. Past ~10 questions pair it with demo 16's sticky sidebar.

Make it yours

  • Start all open: add checked to every input — useful for print stylesheets and legal pages.
  • Expand-all buttons: that genuinely needs JS (a master control overriding N independent states) — demo 19 is exactly that, and it drives the same checkboxes so the counter stays truthful.
  • Drop the chip: delete the readout and the two counter utilities; the accordion is self-contained.
  • Prefer <details>? Same multi-open UX with better semantics, but you lose :checked — count with has-[details[open]]: instead.

Gotchas — read before shipping

  • The readout must come after the counted items in DOM order — counters do not flow backwards. Use order-first to place it visually above.
  • counter-reset on the wrong element scopes wrong the moment two demos share a page: reset on the list itself, with a namespaced counter name.
  • after:content-[counter(tfa04open)] needs the function form; content-['...'] with a quoted string prints the literal text.
  • If you later add expand-all JS, drive it through input.checked = true so the CSS counter stays in sync with reality.

Browser support

ChromeSafariFirefoxEdge
111+16.4+128+111+

CSS counters are ancient and the accordion itself works everywhere; the :has()-powered count needs Chrome 105 / Safari 15.4 / Firefox 121. Without :has() the chip reads 0 while the panels work fine.

Techniques used in this demo

Search CodeFronts

Loading…