Card
A borders-only content surface for grouping related information — no shadows, with composable header, content, and footer parts.
- Status
- Since
0.1.0- Accessibility pattern
- presentational grouping
Last updated
Install
Add Card from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/cardUsage
import {
Card,
CardAction,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
<Card>
<CardHeader>
<CardTitle>Account activity</CardTitle>
<CardDescription>A summary of your recent sign-ins.</CardDescription>
</CardHeader>
<CardContent>You signed in from 3 devices in the last 7 days.</CardContent>
</Card>;Anatomy
Card is a compound component built from plain, server-safe divs. Compose the parts inside the
root — every part forwards its ref and exposes a data-slot:
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
<CardDescription>Supporting description text.</CardDescription>
<CardAction>{/* optional top-right control */}</CardAction>
</CardHeader>
<CardContent>{/* main body */}</CardContent>
<CardFooter>{/* actions */}</CardFooter>
</Card>Card— the root surface (data-slot="card"). Borders-only,rounded-lg,bg-card text-card-foreground. Owns thesizedensity (md/sm).CardHeader— top region (data-slot="card-header"). Switches to a two-column grid when aCardActionis present.CardTitle— the heading line (data-slot="card-title").CardDescription— muted supporting text under the title (data-slot="card-description").CardAction— an optional control anchored top-right of the header (data-slot="card-action").CardContent— the main body region (data-slot="card-content").CardFooter— a bottom region with a top border and muted background (data-slot="card-footer"). When a footer is present, the root drops its own bottom padding (pb-0) so the footer sits flush against the bottom edge.
Examples
A card with a header, content, and a footer action row:
Sizes
Card exposes a single size density prop (md / sm). sm tightens the
internal padding (py-3 / px-3 instead of py-4 / px-4), shrinks the part gap
(gap-3 vs gap-4), and steps the title down to text-sm. Set it once on the root —
the header, content, and footer all react via group-data-[size=sm].
Playground
Toggle the density between default and small, then copy the generated JSX.
<Card>
<CardHeader>
<CardTitle>Team plan</CardTitle>
<CardDescription>$20 / user / month</CardDescription>
</CardHeader>
<CardContent>Everything in Pro, plus SSO and audit logs.</CardContent>
</Card>API Reference
Card
| Prop | Type | Default | Description |
|---|---|---|---|
size | "md" | "sm" | "md" | Density of the card. sm tightens the internal padding and gaps. |
Data attributes and CSS variables on Card
| Attribute | Values |
|---|---|
data-size | mirrors a prop or state value |
data-slot | "card" |
CardHeader, CardTitle, CardDescription, CardAction, CardContent, and
CardFooter add no props of their own — each accepts everything a <div>
accepts (className, ref, children, …).
Accessibility
Cardis a presentational grouping element with no implicit ARIA role — give it semantic meaning through its content (a real heading insideCardTitle, arole/aria-labelon the root if it is interactive).CardTitlerenders a styleddiv. When the card should participate in the page outline, place a real heading inside it, for example<CardTitle><h3>Team plan</h3></CardTitle>.- Interactive controls (
CardAction, footer buttons) are native elements and keep their own focus rings — the card never suppressesoutline. - Borders-only by design: the surface is distinguished by
border-border, not a shadow, keeping it legible in high-contrast and forced-colors modes.
| Key | Action |
|---|---|
| Tab | Move focus through interactive controls inside the card (actions, footer buttons). |
| Enter / Space | Activate the focused control. |
| Contract | States tested |
|---|---|
| Behaviour | default |
| Accessibility | native-or-base-ui-semantics, browser-accessibility-test |
| Visual | default |