Card
A <Card> is a bordered, rounded surface that visually groups related content. The Attio-flavored rule: cards group, they don’t decorate. A card without a clear semantic boundary is just a box.
When to use
- A discrete piece of content with its own header + body (a settings group, an entity tile, a stat).
- Grid items that need uniform shape — wrap in
CardGrid.
Don’t use Card for: page-level layout (Cards inside Cards is a code smell), every section header on a page (use a heading + spacing), or a list-row container (lists should be flat per Attio’s pattern).
Default
Recent activity: 3 emails, 1 call, 2 deal-stage changes this week.
<Card> <CardHeader> <CardTitle>Acme Corp</CardTitle> <CardDescription>5 deals · $128K pipeline</CardDescription> </CardHeader> <CardContent> <p>Recent activity: 3 emails, 1 call, 2 deal-stage changes this week.</p> </CardContent> <CardFooter className="border-t pt-4"> <Button size="sm" variant="outline">Open</Button> </CardFooter></Card>With CardAction
<CardAction> slots into the header’s right-aligned column.
<Card> <CardHeader> <CardTitle>Beta integration</CardTitle> <CardDescription>Connected · syncing every 15 minutes</CardDescription> <CardAction> <Badge variant="secondary">Beta</Badge> </CardAction> </CardHeader></Card>CardGrid
Wraps cards in a responsive grid (1 / 2 / 3 / 4 columns). Single column on mobile, multi-column at md and up.
<CardGrid columns={3}> <Card>…</Card> <Card>…</Card> <Card>…</Card></CardGrid>API
Card
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Forwarded. Use only for spacing/sizing — not for color. |
...rest | HTMLAttributes<HTMLDivElement> | — | All native div attributes. |
CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction
All are slot wrappers. They accept className and forward all native div attributes. CardAction is auto-aligned to the right column of CardHeader.
CardGrid
| Prop | Type | Default | Description |
|---|---|---|---|
columns | 2 | 3 | 4 | 3 | Desktop column count. 4 collapses to 2 columns at md and 4 at lg. |
children * | ReactNode | — | Cards (or any equally-sized item). |
className | string | — | Forwarded. |
Design guidelines
✓ Do
- Use Card for entities and settings groups. Title at top, action top-right, content below.
- Match all cards on a page in shape. Mixed paddings/heights look broken.
- Put the divider above CardFooter via `className="border-t pt-4"` only when the footer changes the meaning of the card (action vs. metadata).
✗ Don't
- Wrap a list table in a Card. Tables are flat per the spec — see Attio Layout.
- Nest cards. If two cards belong together, the outer one should not be a card.
- Use a card to add a "shadow" for emphasis. The card is structure, not decoration.
Accessibility
CardTitledefaults to a<div>— slot it under a section heading rather than relying on it as the heading itself for screen readers.- Cards aren’t focusable by default. Make them clickable by wrapping in
<a>only when the whole card is the link target — otherwise use buttons inside.
Related
StatRow— Compact stat with delta.ContentSection— When you want a titled body section without a card border.PropertyList— Key/value entity layout for inside cards.