{"slug":"card-list","meta":{"title":"Card List","slug":"card-list","kind":"pattern","summary":"Records shown as individual bordered blocks rather than table rows — right for a few important, visual or heterogeneous things, and wrong for forty similar ones.","problem":"Cards get chosen because they photograph well, then applied to a list of forty homogeneous records. Nothing lines up, nothing can be compared, and a screen that should have been scannable becomes a scroll marathon.","family":["scan"],"data_shape":["collection"],"principles":["minimize-distance","progressive-disclosure"],"interaction":["scanning"],"density":"low","complexity":"low","status":"stable","visibility":"public","use_when":["There are few records — roughly under fifteen — and they will stay few.","Records are heterogeneous, so a shared column set would be half empty.","The record's value is visual — a photo, a chart, a preview, a floor plan.","Each item is individually important and chosen deliberately, not compared in bulk."],"avoid_when":["Records are homogeneous and people compare them. Use a table.","The list will grow. Cards degrade with volume in a way tables do not.","The main job is finding one row, which is scanning, and scanning wants alignment."],"alternatives":[{"slug":"dense-operational-table","when":"Records share the same fields and people compare across them. This is the usual answer."},{"slug":"grouped-list","when":"The records are similar but fall into meaningful sets that should be visually separated."}],"ask_leo":"Render this collection as cards rather than table rows, and keep them\ndisciplined.\n\n- Give every card the same internal structure in the same order, so the eye\n  learns one shape and reuses it.\n- Put the identifying name first and make it the largest thing on the card.\n- Limit each card to about five elements. A card is not a place to show the\n  whole record.\n- Keep cards a consistent height in a row so the grid does not ragged out.\n- If the record has an image, it is the reason to use a card — give it real\n  space rather than a thumbnail in a corner.\n- Make the whole card the click target, not just the title.\n- If this collection can exceed about fifteen items, build a table instead and\n  reserve cards for a small featured set above it.\n","related":[{"title":"Dense Operational Table","url":"/patterns/dense-operational-table","summary":"The alternative, and the right answer more often than teams expect."}]},"body":"## Anatomy\n\n```\n┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐\n│ [ image ]        │  │ [ image ]        │  │ [ image ]        │\n│ Riverside Fit-Out│  │ Harbour Depot    │  │ Kestrel Joinery  │\n│ Leeds · Dana     │  │ Hull · Sam       │  │ Grimsby · Priya  │\n│ 6 open jobs      │  │ 2 open jobs      │  │ 1 open job       │\n└──────────────────┘  └──────────────────┘  └──────────────────┘\n   same structure, same order, same height, every card\n```\n\n- **One shape, repeated.** The eye learns the card layout once; every deviation\n  costs that learning back.\n- **A five-element ceiling.** Cards invite accumulation because there is visible\n  space. The space is not free — it is the reason the list scrolls.\n- **Consistent height per row**, or the grid ragged-edges and stops reading as a\n  set.\n\n## Why it works, when it works\n\nCards buy **containment**. Each record is visibly one thing, which is exactly\nright when records differ from one another — a product with a photo, a report\nwith a chart, a template with a preview. Containment is what a table cannot\ngive, because a table's power comes from records sharing a structure.\n\nThey also buy space for a genuinely visual payload. A photograph in a table row\nis a thumbnail; in a card it is the point.\n\n## Why it usually does not work\n\nFor homogeneous records, cards destroy the one thing that makes a collection\nreadable: **alignment**. Values in a table column share an edge, so the eye\ncompares them before reading. Cards place every value in its own coordinate\nspace, so forty records means forty separate readings.\n\nThe house rule from the design guidance is direct: for long lists, a condensed\ntable beats large whitespace-heavy cards; reserve roomy cards for a few\nhigh-importance items. This is the named anti-pattern **card soup** — twenty\nhomogeneous records rendered as enormous cards, usually chosen because the\nmockup with six looked good.\n\n## The test\n\nAsk: **would anyone ever want to compare this field across records?** If yes —\namounts, dates, statuses, counts — those values want a column. If the honest\nanswer is that people pick one item and act on it, cards are fine.\n\nThen ask how many records there will be in a year. Cards that work at eight\nrarely work at eighty, and the migration is a rewrite of the screen.\n\n## Getting it wrong\n\n- **Card soup.** The default failure. Homogeneous rows, huge boxes, no\n  comparison possible.\n- **Ragged heights**, so the grid never resolves into a set.\n- **Cards that grew into records.** Twelve fields per card is a table that has\n  been folded up and made unsortable.\n- **Only the title clickable**, so most of a large target does nothing.\n\n## Exemplars\n\n**Airbnb search results** are the strongest case for cards: the photograph\ngenuinely is the information, records are heterogeneous, and people choose one\nrather than compare fifty on a metric.\n\n**Figma's file browser** shows the previews-are-the-point argument — a filename\nlist would be strictly worse because recognising a design by its thumbnail is\nthe whole task.\n\n**Stripe** is the useful counter-example: almost nothing in the dashboard is a\ncard, because almost everything is a homogeneous record people compare.\n\nThe extractable rule: **cards are for recognition, tables are for comparison.**\nDecide which one the person is doing, and the choice makes itself.\n"}