Card
The section surface: 22px corners, a hairline edge drawn as a shadow, and the heading face on the title. Seven parts compose a header, a body and a footer. Source: src/components/ui/card.tsx.
Anatomy
CardHeader holds the title, description and an optional CardAction pinned top-right. CardContent is the body. CardFooter is a tinted strip with a hairline above it; the card drops its bottom padding when one is present.
Sizes
size sets one variable, --card-spacing, and every part pads from it. sm is for dense grids; none hands the padding to the content, for a card that wraps a table or an image.
Interactive
variant="interactive" with asChild around a Link: the whole card is one target and lifts its shadow on hover. Focus falls back to the global outline; the variant has no focus or press style of its own yet.
Ruled header
Give CardHeader a border-b and it adds its own bottom padding, so a figure or a list sits under a hairline without extra spacing.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "default" | "sm" | "none" | "default" | Card. Sets --card-spacing (16px, 12px, 0), which every part reads for its padding and gap. |
| variant | "default" | "interactive" | "default" | Card. interactive adds a shadow-card-hover lift on the slow duration. No focus or press style of its own. |
| asChild | boolean | false | Card. Render the single child (a Link, an li, a button) as the shell, via Radix Slot. |
| className | string | — | Every part. Merged last. |
| ...props | ComponentProps<"div"> | — | Every part is a div with a data-slot: card, card-header, card-title, card-description, card-action, card-content, card-footer. |
Best practices
When to use
- Group content that belongs together and can be read on its own: a setting, an integration, a summary figure.
- Not for every block on a page. A list of rows reads better as rows divided by hairlines.
Behavior
- One target per card. If the whole card links, don't put other buttons inside it; nested interactive elements fight for the click.
- CardAction takes one control (a menu, a status badge). More than one belongs in the footer.
- Keep cards on the secondary surface or the canvas; the hairline edge is tuned for both.
Accessibility
- CardTitle is a div. When the card starts a section, pass an h2 or h3 inside it (or use asChild on a heading) so the outline makes sense.
- An interactive card must be a real link or button via asChild, never a div with onClick.
- Icon-only actions in CardAction need an aria-label.
Content
- Title in sentence case, a few words. Description: one line that says what it is or when it runs.
- Footer actions right-aligned, the primary action last.