01 / 13
All 13 in 13 Tailwind CSS Tables
- 01Responsive Tailwind Table That Stacks into Cards on Mobile
- 02Tailwind CSS Pricing Comparison Table with Billing Toggle
- 03Tailwind Admin Dashboard Data Table with Sticky Header, Filter & Sort
- 04Dark Neon Crypto Price Table in Tailwind CSS
- 05Tailwind Shopping Cart Table with Quantity Stepper & Live Totals
- 06Glassmorphism Striped Table in Tailwind CSS
- 07Tailwind Table with Sticky First Column & Horizontal Scroll
- 08Minimal Editorial Table Design in Tailwind CSS
- 09Tailwind Checkbox Table with :has() Row States & Progress Bar
- 10Tailwind Weekly Class Schedule Timetable
- 11Nutrition Facts Label in Tailwind CSS
- 12Neumorphic Table Design in Tailwind CSS
- 13Tailwind Table with Frosted Glass Sticky Header
Responsive Tailwind Table That Stacks into Cards on Mobile
The most-searched table problem, solved without a media query: a team-member table that collapses into labelled cards when its container is narrow. Column labels are generated with before:content-[attr(data-label)], the header goes sr-only instead of vanishing, and the whole collapse lives on one tbody class list.
Mosaic by Cruip: a complete Tailwind admin dashboard template in HTML, React, Next.js and Vue · $69
Cruip · Mosaic by Cruip · Affiliate link
The code
<section class="ttb-01 grid-cols-1 w-full min-h-svh grid place-items-center bg-ttb01-bg bg-[radial-gradient(80%_60%_at_50%_0%,var(--color-ttb01-glow),transparent_70%)] px-5 py-14 font-ttb01-sans text-ttb01-ink" aria-label="Responsive stacked table demo">
<div class="@container/tbl w-full max-w-4xl">
<header class="mb-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3.5">
<span aria-hidden="true" class="grid size-11 place-items-center rounded-xl bg-linear-135 from-ttb01-acc to-ttb01-acc2 shadow-[0_10px_24px_-8px_var(--color-ttb01-acc)]">
<svg class="size-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7M18.5 20a6.5 6.5 0 0 0-3-5.6"/></svg>
</span>
<div>
<h2 class="text-xl font-bold tracking-tight">Team members</h2>
<p class="mt-0.5 text-sm text-ttb01-mut">4 people · narrow the stage to see rows become cards</p>
</div>
</div>
<button type="button" class="inline-flex min-h-11 items-center gap-2 rounded-xl bg-ttb01-acc px-4 text-sm font-semibold text-white shadow-[0_8px_20px_-8px_var(--color-ttb01-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ttb01-acc2">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Invite member
</button>
</header>
<div class="overflow-hidden rounded-2xl border border-ttb01-line bg-ttb01-card shadow-[0_24px_60px_-24px_oklch(0_0_0/0.75)] @max-[40rem]/tbl:overflow-visible @max-[40rem]/tbl:border-0 @max-[40rem]/tbl:bg-transparent @max-[40rem]/tbl:shadow-none">
<table class="w-full border-collapse text-left text-sm @max-[40rem]/tbl:block">
<caption class="sr-only">Team members with role, status and join date</caption>
<thead class="bg-linear-to-r from-ttb01-acc/15 to-ttb01-acc2/5 @max-[40rem]/tbl:sr-only">
<tr class="border-b border-ttb01-line [&_th]:px-5 [&_th]:py-3.5 [&_th]:text-[11px] [&_th]:font-bold [&_th]:tracking-[0.14em] [&_th]:text-ttb01-mut [&_th]:uppercase">
<th scope="col" class="text-ttb01-acc2!">User</th>
<th scope="col">Role</th>
<th scope="col">Status</th>
<th scope="col">Joined</th>
<th scope="col" class="text-right"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody class="divide-y divide-ttb01-line [&_td]:px-5 [&_td]:py-4 [&_td]:align-middle [&_tr]:transition-[background-color,box-shadow] [&_tr]:duration-200 [&_tr:hover]:bg-ttb01-acc/8 [&_tr:hover]:shadow-[inset_3px_0_0_var(--color-ttb01-acc)] @max-[40rem]/tbl:grid @max-[40rem]/tbl:gap-3 @max-[40rem]/tbl:[&_tr]:block @max-[40rem]/tbl:[&_tr]:overflow-hidden @max-[40rem]/tbl:[&_tr]:rounded-2xl @max-[40rem]/tbl:[&_tr]:border @max-[40rem]/tbl:[&_tr]:border-ttb01-line @max-[40rem]/tbl:[&_tr]:bg-ttb01-card @max-[40rem]/tbl:[&_td]:flex @max-[40rem]/tbl:[&_td]:items-center @max-[40rem]/tbl:[&_td]:justify-between @max-[40rem]/tbl:[&_td]:gap-4 @max-[40rem]/tbl:[&_td]:py-3 @max-[40rem]/tbl:[&_td:not(:last-child)]:border-b @max-[40rem]/tbl:[&_td]:border-ttb01-line @max-[40rem]/tbl:[&_td]:before:content-[attr(data-label)] @max-[40rem]/tbl:[&_td]:before:text-[10.5px] @max-[40rem]/tbl:[&_td]:before:font-bold @max-[40rem]/tbl:[&_td]:before:tracking-[0.14em] @max-[40rem]/tbl:[&_td]:before:text-ttb01-mut @max-[40rem]/tbl:[&_td]:before:uppercase">
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-ttb01-acc to-ttb01-acc2 text-[13px] font-bold text-white ring-2 ring-ttb01-card">AK</span>
<div class="text-left"><div class="font-semibold">Arya Kapoor</div><div class="text-xs text-ttb01-mut">arya@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Admin</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-01-12">Jan 12, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-rose-400 to-orange-300 text-[13px] font-bold text-white ring-2 ring-ttb01-card">MR</span>
<div class="text-left"><div class="font-semibold">Marcus Reid</div><div class="text-xs text-ttb01-mut">m.reid@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Developer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-warn/12 px-2.5 py-1 text-xs font-semibold text-ttb01-warn"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Pending</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-03-04">Mar 4, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-emerald-400 to-cyan-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">SN</span>
<div class="text-left"><div class="font-semibold">Selin Novak</div><div class="text-xs text-ttb01-mut">selin@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Designer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-05-19">May 19, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-red-400 to-violet-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">TW</span>
<div class="text-left"><div class="font-semibold">Theo Walsh</div><div class="text-xs text-ttb01-mut">theo@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Manager</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-bad/12 px-2.5 py-1 text-xs font-semibold text-ttb01-bad"><span aria-hidden="true" class="size-1.5 rounded-full bg-current"></span>Inactive</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2024-11-02">Nov 2, 2024</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section><section class="ttb-01 grid-cols-1 w-full min-h-svh grid place-items-center bg-ttb01-bg bg-[radial-gradient(80%_60%_at_50%_0%,var(--color-ttb01-glow),transparent_70%)] px-5 py-14 font-ttb01-sans text-ttb01-ink" aria-label="Responsive stacked table demo">
<div class="@container/tbl w-full max-w-4xl">
<header class="mb-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3.5">
<span aria-hidden="true" class="grid size-11 place-items-center rounded-xl bg-linear-135 from-ttb01-acc to-ttb01-acc2 shadow-[0_10px_24px_-8px_var(--color-ttb01-acc)]">
<svg class="size-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7M18.5 20a6.5 6.5 0 0 0-3-5.6"/></svg>
</span>
<div>
<h2 class="text-xl font-bold tracking-tight">Team members</h2>
<p class="mt-0.5 text-sm text-ttb01-mut">4 people · narrow the stage to see rows become cards</p>
</div>
</div>
<button type="button" class="inline-flex min-h-11 items-center gap-2 rounded-xl bg-ttb01-acc px-4 text-sm font-semibold text-white shadow-[0_8px_20px_-8px_var(--color-ttb01-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ttb01-acc2">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Invite member
</button>
</header>
<div class="overflow-hidden rounded-2xl border border-ttb01-line bg-ttb01-card shadow-[0_24px_60px_-24px_oklch(0_0_0/0.75)] @max-[40rem]/tbl:overflow-visible @max-[40rem]/tbl:border-0 @max-[40rem]/tbl:bg-transparent @max-[40rem]/tbl:shadow-none">
<table class="w-full border-collapse text-left text-sm @max-[40rem]/tbl:block">
<caption class="sr-only">Team members with role, status and join date</caption>
<thead class="bg-linear-to-r from-ttb01-acc/15 to-ttb01-acc2/5 @max-[40rem]/tbl:sr-only">
<tr class="border-b border-ttb01-line [&_th]:px-5 [&_th]:py-3.5 [&_th]:text-[11px] [&_th]:font-bold [&_th]:tracking-[0.14em] [&_th]:text-ttb01-mut [&_th]:uppercase">
<th scope="col" class="text-ttb01-acc2!">User</th>
<th scope="col">Role</th>
<th scope="col">Status</th>
<th scope="col">Joined</th>
<th scope="col" class="text-right"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody class="divide-y divide-ttb01-line [&_td]:px-5 [&_td]:py-4 [&_td]:align-middle [&_tr]:transition-[background-color,box-shadow] [&_tr]:duration-200 [&_tr:hover]:bg-ttb01-acc/8 [&_tr:hover]:shadow-[inset_3px_0_0_var(--color-ttb01-acc)] @max-[40rem]/tbl:grid @max-[40rem]/tbl:gap-3 @max-[40rem]/tbl:[&_tr]:block @max-[40rem]/tbl:[&_tr]:overflow-hidden @max-[40rem]/tbl:[&_tr]:rounded-2xl @max-[40rem]/tbl:[&_tr]:border @max-[40rem]/tbl:[&_tr]:border-ttb01-line @max-[40rem]/tbl:[&_tr]:bg-ttb01-card @max-[40rem]/tbl:[&_td]:flex @max-[40rem]/tbl:[&_td]:items-center @max-[40rem]/tbl:[&_td]:justify-between @max-[40rem]/tbl:[&_td]:gap-4 @max-[40rem]/tbl:[&_td]:py-3 @max-[40rem]/tbl:[&_td:not(:last-child)]:border-b @max-[40rem]/tbl:[&_td]:border-ttb01-line @max-[40rem]/tbl:[&_td]:before:content-[attr(data-label)] @max-[40rem]/tbl:[&_td]:before:text-[10.5px] @max-[40rem]/tbl:[&_td]:before:font-bold @max-[40rem]/tbl:[&_td]:before:tracking-[0.14em] @max-[40rem]/tbl:[&_td]:before:text-ttb01-mut @max-[40rem]/tbl:[&_td]:before:uppercase">
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-ttb01-acc to-ttb01-acc2 text-[13px] font-bold text-white ring-2 ring-ttb01-card">AK</span>
<div class="text-left"><div class="font-semibold">Arya Kapoor</div><div class="text-xs text-ttb01-mut">arya@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Admin</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-01-12">Jan 12, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-rose-400 to-orange-300 text-[13px] font-bold text-white ring-2 ring-ttb01-card">MR</span>
<div class="text-left"><div class="font-semibold">Marcus Reid</div><div class="text-xs text-ttb01-mut">m.reid@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Developer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-warn/12 px-2.5 py-1 text-xs font-semibold text-ttb01-warn"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Pending</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-03-04">Mar 4, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-emerald-400 to-cyan-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">SN</span>
<div class="text-left"><div class="font-semibold">Selin Novak</div><div class="text-xs text-ttb01-mut">selin@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Designer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-05-19">May 19, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-red-400 to-violet-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">TW</span>
<div class="text-left"><div class="font-semibold">Theo Walsh</div><div class="text-xs text-ttb01-mut">theo@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Manager</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-bad/12 px-2.5 py-1 text-xs font-semibold text-ttb01-bad"><span aria-hidden="true" class="size-1.5 rounded-full bg-current"></span>Inactive</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2024-11-02">Nov 2, 2024</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>@import "tailwindcss";
@theme {
--color-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}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-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}@import "tailwindcss";
@theme {
--color-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}<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&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;700;800&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The original's twelve-line
@media (max-width:640px)block became@max-[40rem]/tbl:variants on onetbody— a container query, so the collapse now triggers inside narrow playgrounds, sidebars and modals, not only on phones. td::before { content: attr(data-label) }isbefore:content-[attr(data-label)], applied to every cell at once through[&_td]:before:.- UI upgrade from the CSS original:
thead { display:none }becamesr-only, so screen-reader users keep the column headers; the hovertranslateX(3px)that nudged the whole row (and its text) became a layout-stable inset accent rail. - UI upgrade: emoji icon and "Edit / Del" text buttons replaced with aria-labelled 44px icon buttons, join dates are real
<time>elements, muted copy raised from#888ab0to 7.4:1, and an Invite member primary action anchors the header.
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: Responsive Tailwind Table That Stacks into Cards on Mobile
Source: https://codefronts.com/snippets/tailwind-css-tables/responsive-tailwind-table-stacks-into-cards-on-mobile/
The most-searched table problem, solved without a media query: a team-member table that collapses into labelled cards when its container is narrow. Column labels are generated with before:content-[attr(data-label)], the header goes sr-only instead of vanishing, and the whole collapse lives on one tbody class list.
## HTML
```html
<section class="ttb-01 grid-cols-1 w-full min-h-svh grid place-items-center bg-ttb01-bg bg-[radial-gradient(80%_60%_at_50%_0%,var(--color-ttb01-glow),transparent_70%)] px-5 py-14 font-ttb01-sans text-ttb01-ink" aria-label="Responsive stacked table demo">
<div class="@container/tbl w-full max-w-4xl">
<header class="mb-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3.5">
<span aria-hidden="true" class="grid size-11 place-items-center rounded-xl bg-linear-135 from-ttb01-acc to-ttb01-acc2 shadow-[0_10px_24px_-8px_var(--color-ttb01-acc)]">
<svg class="size-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7M18.5 20a6.5 6.5 0 0 0-3-5.6"/></svg>
</span>
<div>
<h2 class="text-xl font-bold tracking-tight">Team members</h2>
<p class="mt-0.5 text-sm text-ttb01-mut">4 people · narrow the stage to see rows become cards</p>
</div>
</div>
<button type="button" class="inline-flex min-h-11 items-center gap-2 rounded-xl bg-ttb01-acc px-4 text-sm font-semibold text-white shadow-[0_8px_20px_-8px_var(--color-ttb01-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ttb01-acc2">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Invite member
</button>
</header>
<div class="overflow-hidden rounded-2xl border border-ttb01-line bg-ttb01-card shadow-[0_24px_60px_-24px_oklch(0_0_0/0.75)] @max-[40rem]/tbl:overflow-visible @max-[40rem]/tbl:border-0 @max-[40rem]/tbl:bg-transparent @max-[40rem]/tbl:shadow-none">
<table class="w-full border-collapse text-left text-sm @max-[40rem]/tbl:block">
<caption class="sr-only">Team members with role, status and join date</caption>
<thead class="bg-linear-to-r from-ttb01-acc/15 to-ttb01-acc2/5 @max-[40rem]/tbl:sr-only">
<tr class="border-b border-ttb01-line [&_th]:px-5 [&_th]:py-3.5 [&_th]:text-[11px] [&_th]:font-bold [&_th]:tracking-[0.14em] [&_th]:text-ttb01-mut [&_th]:uppercase">
<th scope="col" class="text-ttb01-acc2!">User</th>
<th scope="col">Role</th>
<th scope="col">Status</th>
<th scope="col">Joined</th>
<th scope="col" class="text-right"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody class="divide-y divide-ttb01-line [&_td]:px-5 [&_td]:py-4 [&_td]:align-middle [&_tr]:transition-[background-color,box-shadow] [&_tr]:duration-200 [&_tr:hover]:bg-ttb01-acc/8 [&_tr:hover]:shadow-[inset_3px_0_0_var(--color-ttb01-acc)] @max-[40rem]/tbl:grid @max-[40rem]/tbl:gap-3 @max-[40rem]/tbl:[&_tr]:block @max-[40rem]/tbl:[&_tr]:overflow-hidden @max-[40rem]/tbl:[&_tr]:rounded-2xl @max-[40rem]/tbl:[&_tr]:border @max-[40rem]/tbl:[&_tr]:border-ttb01-line @max-[40rem]/tbl:[&_tr]:bg-ttb01-card @max-[40rem]/tbl:[&_td]:flex @max-[40rem]/tbl:[&_td]:items-center @max-[40rem]/tbl:[&_td]:justify-between @max-[40rem]/tbl:[&_td]:gap-4 @max-[40rem]/tbl:[&_td]:py-3 @max-[40rem]/tbl:[&_td:not(:last-child)]:border-b @max-[40rem]/tbl:[&_td]:border-ttb01-line @max-[40rem]/tbl:[&_td]:before:content-[attr(data-label)] @max-[40rem]/tbl:[&_td]:before:text-[10.5px] @max-[40rem]/tbl:[&_td]:before:font-bold @max-[40rem]/tbl:[&_td]:before:tracking-[0.14em] @max-[40rem]/tbl:[&_td]:before:text-ttb01-mut @max-[40rem]/tbl:[&_td]:before:uppercase">
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-ttb01-acc to-ttb01-acc2 text-[13px] font-bold text-white ring-2 ring-ttb01-card">AK</span>
<div class="text-left"><div class="font-semibold">Arya Kapoor</div><div class="text-xs text-ttb01-mut">arya@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Admin</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-01-12">Jan 12, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-rose-400 to-orange-300 text-[13px] font-bold text-white ring-2 ring-ttb01-card">MR</span>
<div class="text-left"><div class="font-semibold">Marcus Reid</div><div class="text-xs text-ttb01-mut">m.reid@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Developer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-warn/12 px-2.5 py-1 text-xs font-semibold text-ttb01-warn"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Pending</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-03-04">Mar 4, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-emerald-400 to-cyan-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">SN</span>
<div class="text-left"><div class="font-semibold">Selin Novak</div><div class="text-xs text-ttb01-mut">selin@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Designer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-05-19">May 19, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-red-400 to-violet-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">TW</span>
<div class="text-left"><div class="font-semibold">Theo Walsh</div><div class="text-xs text-ttb01-mut">theo@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Manager</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-bad/12 px-2.5 py-1 text-xs font-semibold text-ttb01-bad"><span aria-hidden="true" class="size-1.5 rounded-full bg-current"></span>Inactive</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2024-11-02">Nov 2, 2024</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}
```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: Responsive Tailwind Table That Stacks into Cards on Mobile
Source: https://codefronts.com/snippets/tailwind-css-tables/responsive-tailwind-table-stacks-into-cards-on-mobile/
The most-searched table problem, solved without a media query: a team-member table that collapses into labelled cards when its container is narrow. Column labels are generated with before:content-[attr(data-label)], the header goes sr-only instead of vanishing, and the whole collapse lives on one tbody class list.
## HTML
```html
<section class="ttb-01 grid-cols-1 w-full min-h-svh grid place-items-center bg-ttb01-bg bg-[radial-gradient(80%_60%_at_50%_0%,var(--color-ttb01-glow),transparent_70%)] px-5 py-14 font-ttb01-sans text-ttb01-ink" aria-label="Responsive stacked table demo">
<div class="@container/tbl w-full max-w-4xl">
<header class="mb-6 flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-3.5">
<span aria-hidden="true" class="grid size-11 place-items-center rounded-xl bg-linear-135 from-ttb01-acc to-ttb01-acc2 shadow-[0_10px_24px_-8px_var(--color-ttb01-acc)]">
<svg class="size-5 text-white" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0"/><path d="M16 4.5a3.5 3.5 0 0 1 0 7M18.5 20a6.5 6.5 0 0 0-3-5.6"/></svg>
</span>
<div>
<h2 class="text-xl font-bold tracking-tight">Team members</h2>
<p class="mt-0.5 text-sm text-ttb01-mut">4 people · narrow the stage to see rows become cards</p>
</div>
</div>
<button type="button" class="inline-flex min-h-11 items-center gap-2 rounded-xl bg-ttb01-acc px-4 text-sm font-semibold text-white shadow-[0_8px_20px_-8px_var(--color-ttb01-acc)] transition hover:brightness-110 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ttb01-acc2">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" aria-hidden="true"><path d="M12 5v14M5 12h14"/></svg>
Invite member
</button>
</header>
<div class="overflow-hidden rounded-2xl border border-ttb01-line bg-ttb01-card shadow-[0_24px_60px_-24px_oklch(0_0_0/0.75)] @max-[40rem]/tbl:overflow-visible @max-[40rem]/tbl:border-0 @max-[40rem]/tbl:bg-transparent @max-[40rem]/tbl:shadow-none">
<table class="w-full border-collapse text-left text-sm @max-[40rem]/tbl:block">
<caption class="sr-only">Team members with role, status and join date</caption>
<thead class="bg-linear-to-r from-ttb01-acc/15 to-ttb01-acc2/5 @max-[40rem]/tbl:sr-only">
<tr class="border-b border-ttb01-line [&_th]:px-5 [&_th]:py-3.5 [&_th]:text-[11px] [&_th]:font-bold [&_th]:tracking-[0.14em] [&_th]:text-ttb01-mut [&_th]:uppercase">
<th scope="col" class="text-ttb01-acc2!">User</th>
<th scope="col">Role</th>
<th scope="col">Status</th>
<th scope="col">Joined</th>
<th scope="col" class="text-right"><span class="sr-only">Actions</span></th>
</tr>
</thead>
<tbody class="divide-y divide-ttb01-line [&_td]:px-5 [&_td]:py-4 [&_td]:align-middle [&_tr]:transition-[background-color,box-shadow] [&_tr]:duration-200 [&_tr:hover]:bg-ttb01-acc/8 [&_tr:hover]:shadow-[inset_3px_0_0_var(--color-ttb01-acc)] @max-[40rem]/tbl:grid @max-[40rem]/tbl:gap-3 @max-[40rem]/tbl:[&_tr]:block @max-[40rem]/tbl:[&_tr]:overflow-hidden @max-[40rem]/tbl:[&_tr]:rounded-2xl @max-[40rem]/tbl:[&_tr]:border @max-[40rem]/tbl:[&_tr]:border-ttb01-line @max-[40rem]/tbl:[&_tr]:bg-ttb01-card @max-[40rem]/tbl:[&_td]:flex @max-[40rem]/tbl:[&_td]:items-center @max-[40rem]/tbl:[&_td]:justify-between @max-[40rem]/tbl:[&_td]:gap-4 @max-[40rem]/tbl:[&_td]:py-3 @max-[40rem]/tbl:[&_td:not(:last-child)]:border-b @max-[40rem]/tbl:[&_td]:border-ttb01-line @max-[40rem]/tbl:[&_td]:before:content-[attr(data-label)] @max-[40rem]/tbl:[&_td]:before:text-[10.5px] @max-[40rem]/tbl:[&_td]:before:font-bold @max-[40rem]/tbl:[&_td]:before:tracking-[0.14em] @max-[40rem]/tbl:[&_td]:before:text-ttb01-mut @max-[40rem]/tbl:[&_td]:before:uppercase">
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-ttb01-acc to-ttb01-acc2 text-[13px] font-bold text-white ring-2 ring-ttb01-card">AK</span>
<div class="text-left"><div class="font-semibold">Arya Kapoor</div><div class="text-xs text-ttb01-mut">arya@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Admin</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-01-12">Jan 12, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Arya Kapoor" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-rose-400 to-orange-300 text-[13px] font-bold text-white ring-2 ring-ttb01-card">MR</span>
<div class="text-left"><div class="font-semibold">Marcus Reid</div><div class="text-xs text-ttb01-mut">m.reid@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Developer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-warn/12 px-2.5 py-1 text-xs font-semibold text-ttb01-warn"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Pending</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-03-04">Mar 4, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Marcus Reid" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-emerald-400 to-cyan-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">SN</span>
<div class="text-left"><div class="font-semibold">Selin Novak</div><div class="text-xs text-ttb01-mut">selin@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Designer</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-ok/12 px-2.5 py-1 text-xs font-semibold text-ttb01-ok"><span aria-hidden="true" class="size-1.5 rounded-full bg-current animate-ttb01-pulse motion-reduce:animate-none"></span>Active</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2025-05-19">May 19, 2025</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Selin Novak" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
<tr>
<td data-label="User">
<div class="flex items-center gap-3">
<span aria-hidden="true" class="grid size-10 flex-none place-items-center rounded-full bg-linear-135 from-red-400 to-violet-500 text-[13px] font-bold text-white ring-2 ring-ttb01-card">TW</span>
<div class="text-left"><div class="font-semibold">Theo Walsh</div><div class="text-xs text-ttb01-mut">theo@nexuslab.io</div></div>
</div>
</td>
<td data-label="Role"><span class="rounded-md border border-ttb01-acc/30 bg-ttb01-acc/12 px-2 py-1 text-xs font-medium text-ttb01-acc-ink">Manager</span></td>
<td data-label="Status"><span class="inline-flex items-center gap-1.5 rounded-full bg-ttb01-bad/12 px-2.5 py-1 text-xs font-semibold text-ttb01-bad"><span aria-hidden="true" class="size-1.5 rounded-full bg-current"></span>Inactive</span></td>
<td data-label="Joined" class="text-[13px] text-ttb01-mut tabular-nums"><time datetime="2024-11-02">Nov 2, 2024</time></td>
<td data-label="Actions">
<div class="flex justify-end gap-1.5">
<button type="button" aria-label="Edit Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-acc/15 hover:text-ttb01-acc-ink focus-visible:outline-2 focus-visible:outline-ttb01-acc2"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h4L19 9l-4-4L4 16z"/><path d="M13.5 6.5l4 4"/></svg></button>
<button type="button" aria-label="Remove Theo Walsh" class="grid size-11 place-items-center rounded-xl text-ttb01-mut transition hover:bg-ttb01-bad/15 hover:text-ttb01-bad focus-visible:outline-2 focus-visible:outline-ttb01-bad"><svg class="size-4.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13"/></svg></button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-ttb01-bg: #0e0f1a;
--color-ttb01-bg: oklch(0.17 0.025 280);
--color-ttb01-glow: #252554;
--color-ttb01-glow: oklch(0.28 0.09 280 / 0.7);
--color-ttb01-card: #181a2b;
--color-ttb01-card: oklch(0.22 0.03 280);
--color-ttb01-line: #2a2c46;
--color-ttb01-line: oklch(0.3 0.045 280);
--color-ttb01-ink: #e7e7f5;
--color-ttb01-ink: oklch(0.93 0.015 285);
--color-ttb01-mut: #a4a7c6;
--color-ttb01-mut: oklch(0.74 0.04 280);
--color-ttb01-acc: #7a6fff;
--color-ttb01-acc: oklch(0.62 0.2 282);
--color-ttb01-acc-ink: #b9b3ff;
--color-ttb01-acc-ink: oklch(0.8 0.1 285);
--color-ttb01-acc2: #22d3ee;
--color-ttb01-acc2: oklch(0.8 0.13 210);
--color-ttb01-ok: #34d399;
--color-ttb01-ok: oklch(0.78 0.15 165);
--color-ttb01-warn: #fbbf24;
--color-ttb01-warn: oklch(0.84 0.16 85);
--color-ttb01-bad: #f87171;
--color-ttb01-bad: oklch(0.71 0.17 22);
--font-ttb01-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--animate-ttb01-pulse: ttb01-pulse 2s ease-in-out infinite;
@keyframes ttb01-pulse {
0%,
100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.45;
transform: scale(0.7);
}
}
}
/* Root rule: the full-bleed contract, stated in CSS as well as in the markup's utilities, so the
stage is sized before the browser build compiles. */
.ttb-01 {
width: 100%;
min-height: 100svh;
}
```How this works
One container, one breakpoint. The wrapper is @container/tbl; every collapse rule is prefixed @max-[40rem]/tbl:, so the table re-stacks based on the space it is given rather than the viewport:
<tbody class="@max-[40rem]/tbl:grid @max-[40rem]/tbl:gap-3
@max-[40rem]/tbl:[&_tr]:block @max-[40rem]/tbl:[&_td]:flex
@max-[40rem]/tbl:[&_td]:before:content-[attr(data-label)]">Descendant variants keep the markup readable. Instead of repeating twenty utilities on every <td>, the rules sit once on tbody through [&_td]: and [&_tr]:. Stacked variants apply left to right: the container query wraps the descendant selector, which wraps ::before.
Desktop dividers use divide-y, which emits a zero-specificity :where() selector — so the card-mode [&_tr]:border wins cleanly without !important.
Make it yours
- Change the breakpoint: replace every
@max-[40rem]/tbl:with@max-[48rem]/tbl:to collapse at tablet widths. - Re-theme: edit
--color-ttb01-accand--color-ttb01-acc2in@theme— the header wash, avatars, role chips and rail all follow. - New status: copy a badge and swap
bg-ttb01-ok/12 text-ttb01-okfor any palette colour, e.g.bg-sky-400/12 text-sky-300. - Wider labels: add
@max-[40rem]/tbl:[&_td]:before:min-w-24to align values in a column.
Gotchas — read before shipping
display:blockon table parts dropscolspan/rowspanin card mode — keep collapsible rows to single-span cells.- Some screen readers drop table semantics once rows are
display:block; the visibledata-labeltext keeps each value self-describing. data-labelmust be kept in sync with the<th>text by hand — generate both from one source in a component.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Size container queries are Chrome 105 / Safari 16 / Firefox 110; attr() in content is universal. The floor is Tailwind v4's generated sheet.