01. Responsive Collapse Table (opens in a new tab)
data-label attributes — no JavaScript required.13 CSS tables for SaaS pricing comparisons, admin dashboards, shopping carts, crypto trackers, and class timetables — spanning responsive collapse-to-card layouts, sticky headers and pinned first columns, :has()-driven row focus states, zebra glassmorphism and neumorphic surfaces, an FDA Nutrition Facts panel, and a frosted Liquid Glass header. Scoped under .ct-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.
Related21 CSS Pricing Tables21 CSS Pricing Sections30 CSS Grid Layouts13 Tailwind CSS Tables
Premium template pickPartner: Cruip
Affiliate linkBuilding the whole admin dashboard, not just this layout?
You just browsed 13 table styles. Mosaic by Cruip is a complete Tailwind CSS admin dashboard template, coded in HTML, React, Next.js, Vue and Laravel, with a Figma version too. It costs $69.
Mosaic by Cruip. We may earn a commission, at no extra cost to you.
data-label attributes — no JavaScript required.col groups and custom properties.position: sticky header row, colourful status badges, gradient avatars, and sortable-column affordances — grounded in a GitHub-dark design language.<tbody> dims all rows to 40% opacity and the hovered row glows back to full brightness with a cyan left-border laser line.backdrop-filter: blur() on alternating rows to create a frost-over-glass zebra stripe effect.:has() pseudo-class with a JS progress bar.border-width hierarchy (thick, medium, thin), and a scanning accent line animation — no images required.box-shadow neumorphic depth.data-label attribute on each cell. In the markup, you add data-label='Email' to every td that contains an email value (and the same for every other column). Above mobile width, the standard table renders normally with thead headers. Below mobile (@media (max-width: 720px)), you flip table, thead, tbody, tr, td to display: block, visually hide the thead with clip-path: inset(50%), set each td to relative positioning, and pseudo-element each cell with td::before { content: attr(data-label); font-weight: 600; }. The browser pulls the label from the data-label attribute and renders it inline above the value, producing a card-stacked layout on phones. CSS-Tricks coined this in 2016 and it's still the canonical pattern in 2026 — it works in every browser, requires zero JS, and degrades gracefully if the user disables CSS. Demo 01 ships the full recipe.position: sticky; left: 0 on the first-column cells. The full recipe: wrap the table in a horizontally-scrollable container (overflow-x: auto), then apply position: sticky; left: 0; background: var(--surface) to both the th:first-child and td:first-child selectors. The background color is critical — without it, the scrolling cells visually 'bleed through' the sticky column as they pass under it. Add z-index: 2 on the sticky header cell (thead th:first-child) so it stays above the regular row cells when both are sticking. Browser support is universal as of 2026 (Chrome 56+, Safari 13+, Firefox 32+). Common gotcha: any ancestor with overflow: hidden breaks sticky positioning — the sticky element needs at least one scrollable ancestor with overflow: auto or overflow: scroll. Demo 07 (Fixed First Column Data Sheet) ships the balance-sheet financial pattern.tbody tr:nth-child(even) { background: rgba(0,0,0,0.04); }. Always use nth-child(even) on rows inside the tbody — not nth-of-type, because nth-of-type targets all sibling tr elements regardless of which tbody they belong to, which breaks if you have multiple tbody sections or a tfoot. For maximum readability, also add tbody tr:hover { background: rgba(124,108,255,0.08); } for a hover preview so users can keep their place across wide rows. For a more atmospheric look, layer zebra striping on top of a glassmorphism surface — alternating rows at 18%/8% white opacity create the depth illusion (Demo 06).scope='col' (column headers) or scope='row' (row headers) so the screen reader knows the relationship. (3) Add a caption element as the FIRST child of the table — it's announced before the table starts and gives blind users context ("Q4 2025 Revenue by Region"). (4) For complex tables with multiple header rows, use headers='id1 id2' on data cells that depend on multiple headers. (5) Avoid using tables for layout — only for tabular data. CSS Grid is the right tool for layout, even when the layout looks grid-like. (6) Provide a brief summary either in caption text or via aria-describedby pointing at a paragraph before the table. WCAG 1.3.1 (Info & Relationships) and 1.3.2 (Meaningful Sequence) both apply. Every demo in this collection ships semantic markup with scope attributes where appropriate.display: grid with grid-template-columns: minmax(180px, 1fr) repeat(auto-fit, minmax(140px, 1fr)). The first column is the feature label (sticky on horizontal scroll if needed), and the auto-fit columns gracefully add/remove based on container width. (2) **Real table with sticky first column**: a semantic table with position: sticky; left: 0 on the first column (see freeze-column FAQ above) for the feature labels. The Stripe / Linear / Vercel pricing pages all use one of these two patterns. Both let you add a 6th plan column without restructuring. Demo 02 (SaaS Pricing Comparison Matrix) ships the table pattern with a highlighted 'Pro' tier via tr.popular { background: var(--accent-soft) } to draw the eye to the recommended plan.th element. (2) On click, read a data-sort-type attribute from the header (values: 'string', 'number', 'date'). (3) Convert the tbody rows to an array via Array.from(tbody.querySelectorAll('tr')). (4) Sort the array by extracting the matching cell's text and comparing per the data-sort-type. (5) Re-append the sorted rows to the tbody (the DOM accepts this without rebuilding). (6) Toggle a data-order='asc' or 'desc' attribute on the th to flip direction on subsequent clicks, and use a CSS rule like th[data-order='asc']::after { content: ' ↑' } to show the sort indicator. That's it. TanStack Table is 50KB+ gzipped; DataTables is 87KB. For a single sortable table, 30 lines of vanilla code outperforms both on first-paint and works without React/jQuery. Demo 03 (Admin Dashboard Data Grid) ships the recipe.data-label cell prefixes to mimic header text inline. Best when each row is a 'record' the user reads individually (contacts, orders, transactions). (b) **Horizontal scroll with scroll-snap** — wrap the table in overflow-x: auto; scroll-snap-type: x mandatory and add scroll-snap-align: start on key columns. Users swipe horizontally, columns snap into focus. Best for true data grids where comparing across columns matters more than reading per-row (analytics, dashboards). (c) **Display: grid reflow** — change table to a CSS grid container at narrow widths so columns auto-stack vertically. Works for short tables with few columns but breaks for tables with 6+ columns. Demos 01 (card-collapse) and 03 (admin grid with scroll) cover (a) and (b).30 hand-coded CSS badges for status indicators, notifications, membership tiers, live-data displays, and SEO / DevOps / financial dashboards — upload progress, typing indicator, transit line status, Core Web Vitals, ECG heartbeat, CI/CD build pipeline, countdown ring, live price ticker, keycap shortcut, wax seal, conference lanyard, and holographic collectibles. Copy-paste HTML and CSS, WCAG 2.2 accessible, MIT licensed.
20 hand-coded CSS banner and alert bars for e-commerce storefronts, SaaS dashboards, marketing sites, and compliance-bound products. Covers GDPR cookie consent with a real preferences panel, promo bars with countdown timers, free-shipping threshold progress, app-install smart banners, maintenance and incident status bars, newsletter signup bars, age verification gates, limited-stock urgency banners, live event announcements, browser upgrade notices, geo and currency switchers, sticky top announcement bars, bottom cookie bars, inline form validation alerts, icon-aligned alert banners, left-border accent alerts, diagonal stripe promos, full-width hero banners, animated gradient border alerts, and a text-wrapping laboratory that shows five strategies for the unbreakable string that breaks more banners than anything else. Every bar is scoped under a .ba-NN prefix for no-collision pasting, guards prefers-reduced-motion, carries the correct aria-live and role semantics, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.
25 CSS blockquotes for article pull quotes, testimonial cards, docs callout admonitions, statement banners, and social-post embeds. Covers giant decorative quotation marks, minimalist hairline and classic left borders, animated gradient and glowing neon borders, glassmorphism and aurora backgrounds, brutalist cards, speech bubbles, thick accent rails, highlighted mark text, newspaper multi-column layouts, an expandable read-more disclosure, a scroll-snap testimonial slider, and one-click copy.