Pricing Table with Collapsible Feature Categories — Free HTML CSS JS Snippet
Pricing Table with Collapsible Feature Categories · Pricing · Plain HTML, CSS & JS · Live preview
Copy & paste
Source Code
<div class="fca-wrap">
<div class="fca-head-row">
<span class="fca-corner">Compare plans</span>
<div class="fca-plan-heads">
<span>Basic</span><span>Pro</span><span class="fca-highlight">Team</span>
</div>
</div>
<div class="fca-table" id="fcaTable">
<div class="fca-category" data-open="true">
<button type="button" class="fca-cat-head">
<span class="fca-cat-title">
<svg class="fca-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
Core features
</span>
<span class="fca-cat-count">5/5 in Team</span>
</button>
<div class="fca-cat-body">
<div class="fca-row"><span>Projects</span><b>3</b><b>Unlimited</b><b>Unlimited</b></div>
<div class="fca-row"><span>Storage</span><b>2 GB</b><b>50 GB</b><b>500 GB</b></div>
<div class="fca-row"><span>File versioning</span><b data-no></b><b data-yes></b><b data-yes></b></div>
<div class="fca-row"><span>Custom templates</span><b data-no></b><b data-yes></b><b data-yes></b></div>
<div class="fca-row"><span>Offline mode</span><b data-yes></b><b data-yes></b><b data-yes></b></div>
</div>
</div>
<div class="fca-category" data-open="false">
<button type="button" class="fca-cat-head">
<span class="fca-cat-title">
<svg class="fca-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
Collaboration
</span>
<span class="fca-cat-count">3/3 in Team</span>
</button>
<div class="fca-cat-body">
<div class="fca-row"><span>Team members</span><b>1</b><b>5</b><b>Unlimited</b></div>
<div class="fca-row"><span>Shared workspaces</span><b data-no></b><b data-yes></b><b data-yes></b></div>
<div class="fca-row"><span>Live commenting</span><b data-no></b><b data-yes></b><b data-yes></b></div>
</div>
</div>
<div class="fca-category" data-open="false">
<button type="button" class="fca-cat-head">
<span class="fca-cat-title">
<svg class="fca-chev" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg>
Security & admin
</span>
<span class="fca-cat-count">1/4 in Team</span>
</button>
<div class="fca-cat-body">
<div class="fca-row"><span>SSO / SAML</span><b data-no></b><b data-no></b><b data-yes></b></div>
<div class="fca-row"><span>Audit logs</span><b data-no></b><b data-no></b><b data-yes></b></div>
<div class="fca-row"><span>Role-based permissions</span><b data-no></b><b data-no></b><b data-yes></b></div>
<div class="fca-row"><span>Two-factor auth</span><b data-yes></b><b data-yes></b><b data-yes></b></div>
</div>
</div>
</div>
</div>*{box-sizing:border-box;margin:0;padding:0}
body{font-family:system-ui,-apple-system,sans-serif;background:#f5f6fb;display:flex;justify-content:center;padding:40px 20px}
.fca-wrap{width:min(720px,96vw)}
.fca-head-row{display:grid;grid-template-columns:1fr 1fr;padding:0 4px 12px}
.fca-corner{align-self:end;font-size:12px;font-weight:700;color:#9aa0b4;text-transform:uppercase;letter-spacing:.03em}
.fca-plan-heads{display:grid;grid-template-columns:repeat(3,1fr);text-align:center}
.fca-plan-heads span{font-size:14px;font-weight:800;color:#16182a;padding-bottom:4px}
.fca-plan-heads .fca-highlight{color:#6366f1}
.fca-table{background:#fff;border:1px solid #e7e9f2;border-radius:16px;overflow:hidden}
.fca-cat-head{width:100%;display:flex;align-items:center;justify-content:space-between;padding:15px 18px;background:#fafbff;border:none;border-bottom:1px solid #eef0f6;cursor:pointer;font-family:inherit}
.fca-cat-title{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:700;color:#16182a}
.fca-chev{color:#9aa0b4;transition:transform .2s;flex-shrink:0}
.fca-category[data-open="true"] .fca-chev{transform:rotate(180deg);color:#6366f1}
.fca-cat-count{font-size:12px;font-weight:700;color:#6366f1;background:#eef0fe;padding:3px 10px;border-radius:99px}
.fca-cat-body{max-height:0;overflow:hidden;transition:max-height .3s ease}
.fca-category[data-open="true"] .fca-cat-body{max-height:600px}
.fca-row{display:grid;grid-template-columns:1fr 1fr 1fr 1fr;align-items:center;padding:12px 18px;font-size:13.5px;border-bottom:1px solid #f4f5fa}
.fca-row:last-child{border-bottom:none}
.fca-row span{color:#3b4156;font-weight:600}
.fca-row b{text-align:center;color:#3b4156;font-weight:700;font-size:13px}
b[data-yes]::after{content:'';display:inline-block;width:16px;height:16px;border-radius:50%;background:#10b981;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/11px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/11px no-repeat}
b[data-no]::after{content:'\2013';color:#c2c6d4;font-weight:700}
@media(max-width:600px){
.fca-row,.fca-plan-heads{font-size:12px}
.fca-cat-title{font-size:13px}
.fca-row{padding:10px 10px}
.fca-cat-head{padding:13px 10px}
}// Each category is an independent collapsible section — clicking a header toggles
// only that section's own data-open state, so multiple categories can be expanded
// at once if the visitor wants to compare more than one area side by side.
var categories = document.querySelectorAll('.fca-category');
categories.forEach(function (category) {
var head = category.querySelector('.fca-cat-head');
head.addEventListener('click', function () {
var isOpen = category.dataset.open === 'true';
category.dataset.open = isOpen ? 'false' : 'true';
head.setAttribute('aria-expanded', String(!isOpen));
});
// Wire up ARIA so the collapse state is announced correctly from the start.
head.setAttribute('aria-expanded', category.dataset.open);
});Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
Pricing Comparison Table Grouped by Feature Category — Collapsible Sections, Not a Flat List

A pricing table with thirty rows in one flat list is exhausting to scan — a buyer who only cares about security features has to wade past storage limits and template settings to find them. This snippet groups every row into named categories (Core features, Collaboration, Security & admin), each collapsed to a single clickable header by default except the first, so the table reads as a short, scannable summary until a visitor opens the category they actually care about.
Independent open/closed state per category, not an accordion
Each .fca-category tracks its own data-open attribute, and clicking its header only ever toggles that one category — there's no "close all others" logic like a single-open accordion. A buyer evaluating both Collaboration and Security limits can have both sections open simultaneously to compare them side by side, which a strict single-open accordion would prevent.
A count badge that previews what's inside without opening it
Each category header shows a badge like "1/4 in Team" — how many of that category's features the highlighted plan actually includes — right in the collapsed header. This means a visitor doesn't have to open Security & admin just to get a rough sense of how security-featured the Team plan is; the badge gives that away before a single click, and the full row-by-row breakdown is only a click away for anyone who wants it.
max-height accordion animation, one detail at a time
Collapsing and expanding a .fca-cat-body uses the same max-height: 0 to fixed-value CSS transition used by a standard accordion FAQ — set high enough (600px) to never clip the tallest category's content, with overflow: hidden doing the actual clipping while collapsed. The chevron icon rotates 180 degrees in sync via the same data-open attribute selector, so the open/closed visual state, the row content, and the chevron direction can never disagree with each other.
Feature cells stay a consistent yes/no/value pattern
Inside each category, rows use either a plain text value (seat counts, storage limits) or the same data-yes/data-no CSS-masked checkmark pattern as a plain feature table — grouping by category changes how rows are organized, not how any individual row is rendered, so it's a drop-in structural upgrade over a flat table rather than a different visual language.
Accessible from the start
Each category header is a real <button> with aria-expanded set on load to match its initial data-open value and kept in sync on every toggle, so a screen reader announces the correct collapsed/expanded state immediately rather than only after the first interaction.
Customizing it
Add a new category by copying a .fca-category block with its own header text, count badge, and .fca-row children — the toggle logic queries all .fca-category elements generically, so no JavaScript changes are needed. Change which category starts open by editing its initial data-open attribute in the HTML.
Step by step
How to Use
- 1Click a category headerCore features starts open by default — click any header to expand or collapse that category.
- 2Open more than one categoryCategories toggle independently, so you can compare Collaboration and Security open at the same time.
- 3Read the count badgeEach header shows how many of that category's features the highlighted plan includes, even while collapsed.
- 4Compare plan columnsEach row shows the value or a check/dash for Basic, Pro, and Team side by side.
- 5Add a new categoryCopy a .fca-category block with its own header and .fca-row children — no JS changes needed.
- 6Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
No. Each .fca-category has its own independent data-open attribute, and clicking a header only toggles that category. Any number of categories can be open at the same time, which matters here because a buyer often wants to compare two different categories (like Collaboration and Security) side by side rather than one at a time.
It shows how many of that category's features the highlighted plan (Team, in this example) actually includes out of the category's total row count — e.g. "1/4 in Team" for Security & admin. It gives a rough sense of coverage before a visitor even opens the section.
The same technique as a standard accordion: .fca-cat-body starts at max-height: 0 with overflow: hidden, and gains a fixed max-height (600px, larger than any category is likely to need) when its parent's data-open attribute is "true", animated via a CSS transition on max-height. The chevron icon rotates 180 degrees using the same data-open attribute selector so it never falls out of sync with the actual open state.
Copy an entire .fca-category block — its .fca-cat-head button with a title, chevron icon, and count badge, plus a .fca-cat-body containing .fca-row children — and paste it into #fcaTable. No JavaScript changes are needed since the toggle logic queries all .fca-category elements generically on page load.
Each category header is a real <button> element, and its aria-expanded attribute is set to match the category's initial data-open value when the page loads, then kept updated on every click. This means a screen reader announces the correct expanded or collapsed state immediately, not just after the first time a category is toggled.
Yes — that is the default setup. Rows like "Storage" show a plain text value per plan (e.g. "2 GB", "50 GB"), while rows like "File versioning" use the data-yes/data-no attributes to render a CSS-masked checkmark or a dash. Both row styles can appear in any category without any special handling.