Card
A surface that groups related content and its actions.
Installation
npx shadcn@latest add https://qure-ui.qure.ai/r/card.jsonUsage
import {
Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle,
} from '@/components/ui/card'<Card>
<CardHeader>
<CardTitle>Chest X-ray</CardTitle>
<CardDescription>Ramesh Kulkarni · 08:14</CardDescription>
</CardHeader>
<CardContent>…</CardContent>
<CardFooter><Button size="sm">Open study</Button></CardFooter>
</Card>A card is worth reaching for when the things inside it belong to one subject — one study, one
patient, one job. It is the wrong choice for a list of peers: four cards in a column are four
borders and four shadows saying nothing, where rows and a Separator say the same thing
quietly.
Composition
<Card> {/* the surface: border, radius, 20px vertical padding */}
<CardHeader> {/* title and description, padded 20px inline */}
<CardTitle> {/* 16/24 semibold — a div, so you choose the heading level */}
<CardDescription> {/* 14/20 secondary text, sitting 2px under the title */}
</CardHeader>
<CardContent> {/* the body, sharing the header's inline padding */}
<CardFooter> {/* a flex row with an 8px gap, for actions */}
</Card>Every part is optional and every one is a plain div — a card is layout, and putting a runtime
behind it would buy nothing. The inline padding lives on the three inner parts rather than on
the root, so a full-bleed child (a table, an image, an Accordion whose dividers should reach
the edges) can opt out simply by not using them.
CardTitle renders a div on purpose. Cards appear at every depth of a page, and hardcoding
h3 would produce documents whose heading outline is decided by a component. Where the outline
matters, put a real heading inside it — <CardTitle><h3>ACC-482913</h3></CardTitle> — or give
the title role="heading" aria-level={3}.
Study summary
The common shape: what the study is, whose it is, one line of context, and the two actions someone would take next. Keep the footer to the actions that belong to this card — a card with five buttons is a form that has lost its heading.
With a status and an inline action
The header is a flex row when something has to sit opposite the title. A Badge is the usual
occupant: status is an attribute of the subject, so it belongs beside the title rather than
buried in the body.
As a metric tile
Header-only cards, with the description above the number reading as its label. Reach for this on a department dashboard, where the border is doing real work separating one figure from the next.
Making a card clickable
Do not put onClick on the Card. A div that responds to clicks is invisible to a keyboard and
to a screen reader. Put a real link or button inside and let it fill the card:
<Card className="relative">
<CardHeader>
<CardTitle>
<a href="/studies/1" className="after:absolute after:inset-0">Chest X-ray</a>
</CardTitle>
</CardHeader>
</Card>The pseudo-element covers the card, so the whole surface is clickable while the accessible name, the focus ring and the status-bar URL all come from the real link.
That trick breaks text selection inside the card, and a second link in the card will sit under
the overlay unless you give it relative z-10. If the card holds two destinations, it wants
two visible links rather than one invisible one.
API Reference
No primitive and no added props. Each part accepts everything a div does, and each carries a
data-slot for styling from a parent.
| Part | Element | Purpose |
|---|---|---|
Card | div | The surface. A flex column with a 16px gap. |
CardHeader | div | Title and description. |
CardTitle | div | 16/24 semibold. Not a heading element — choose your own level. |
CardDescription | div | 14/20 secondary text. |
CardContent | div | The body. |
CardFooter | div | A flex row, 8px gap, for actions. |