# Responsive Table That Becomes Cards on Phones

A shadcn/ui block from the [@weinc](https://we.inc/components?utm_source=shadcn.exchange) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/weinc/responsive-table-that-becomes-cards-on-phones).

- Page, with a live preview: https://shadcn.exchange/r/weinc/responsive-table-that-becomes-cards-on-phones
- Screenshot: https://shadcn.exchange/shot/weinc/responsive-table-that-becomes-cards-on-phones/light.png
- Registry item: https://we.inc/r/responsive-table-that-becomes-cards-on-phones.json
- Listed: 2026-10-29, source last changed 2026-10-29

## Install

```bash
npx shadcn@latest add https://shadcn.exchange/r/weinc/responsive-table-that-becomes-cards-on-phones.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Files

### `components/we-inc/responsive-table-that-becomes-cards-on-phones.tsx`

```tsx
// Below 640px each row becomes a card. The markup stays a real table; labels come from data-label.
const sessions = [
  { cls: "Intro to bouldering", coach: "Ayla Brennan", day: "Mon 18:30", level: "Beginner", spaces: 4 },
  { cls: "Lead climbing skills", coach: "Dev Sharma", day: "Tue 19:00", level: "Intermediate", spaces: 0 },
  { cls: "Youth squad", coach: "Marta Kowal", day: "Wed 16:30", level: "Ages 10 to 15", spaces: 7 },
  { cls: "Technique clinic", coach: "Ayla Brennan", day: "Thu 18:00", level: "All levels", spaces: 2 },
  { cls: "Sunday social climb", coach: "Leo Hart", day: "Sun 10:00", level: "All levels", spaces: 12 },
];
const cell = "px-4 py-3.5 max-sm:flex max-sm:items-center max-sm:justify-between max-sm:gap-4 max-sm:px-0 max-sm:py-1.5 max-sm:before:text-xs max-sm:before:font-semibold max-sm:before:uppercase max-sm:before:tracking-wider max-sm:before:text-stone-500 max-sm:before:content-[attr(data-label)]";

export default function ResponsiveTableThatBecomesCardsOnPhones() {
  return (
    <section className="bg-amber-50 px-5 py-14 sm:py-20">
      <div className="mx-auto max-w-4xl">
        <table className="w-full border-collapse text-left text-sm max-sm:block">
          <caption className="pb-5 text-left max-sm:block">
            <span className="block text-2xl font-semibold tracking-tight text-stone-900">This week at Crux Wall</span>
            <span className="mt-1 block text-[15px] text-stone-600">Book at the desk or in the app. Spaces update every hour.</span>
          </caption>
          <thead className="max-sm:sr-only">
            <tr className="border-b-2 border-stone-900 text-stone-900">
              <th scope="col" className="px-4 py-3 font-semibold">Class</th>
              <th scope="col" className="px-4 py-3 font-semibold">Coach</th>
              <th scope="col" className="px-4 py-3 font-semibold">When</th>
              <th scope="col" className="px-4 py-3 font-semibold">Level</th>
              <th scope="col" className="px-4 py-3 text-right font-semibold">Spaces</th>
            </tr>
          </thead>
          <tbody className="max-sm:block max-sm:space-y-3">
            {sessions.map((s) => (
              <tr key={s.cls} className="border-b border-amber-200 bg-white/0 max-sm:block max-sm:rounded-2xl max-sm:border max-sm:bg-white max-sm:p-4 max-sm:shadow-sm">
                <th scope="row" className="px-4 py-3.5 font-semibold text-stone-900 max-sm:block max-sm:px-0 max-sm:pb-2 max-sm:pt-0 max-sm:text-base">{s.cls}</th>
                <td data-label="Coach" className={`${cell} text-stone-700`}>{s.coach}</td>
                <td data-label="When" className={`${cell} text-stone-700`}>{s.day}</td>
                <td data-label="Level" className={`${cell} text-stone-700`}>{s.level}</td>
                <td data-label="Spaces" className={`${cell} text-right`}>
                  <span className={`rounded-full px-2.5 py-1 text-xs font-semibold ${s.spaces === 0 ? "bg-stone-200 text-stone-700" : s.spaces < 4 ? "bg-amber-200 text-amber-900" : "bg-lime-200 text-lime-900"}`}>
                    {s.spaces === 0 ? "Full" : `${s.spaces} left`}
                  </span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </section>
  );
}
```
