Cards
Examples
Section titled “Examples”Welcome
A short description sits here.
Welcome
A short description sits here.
<div class="card"> <div class="card-body"> <h3 class="card-title">Welcome</h3> <p class="card-description">A short description sits here.</p> <div class="card-actions"> <button class="btn btn-primary btn-sm">Get started</button> <button class="btn btn-ghost btn-sm">Maybe later</button> </div> </div></div><Card title="Welcome" description="A short description sits here." actions={ <> <Button variant="primary" size="sm"> Get started </Button> <Button variant="ghost" size="sm"> Maybe later </Button> </> }/>Sign-in form
Section titled “Sign-in form”Sign in
Sign in
<div class="card"> <div class="card-body"> <h3 class="card-title">Sign in</h3> <input class="input" placeholder="Email" /> <input class="input" type="password" placeholder="Password" /> <div class="card-actions"> <button class="btn btn-primary">Sign in</button> <button class="btn btn-ghost">Cancel</button> </div> </div></div><Card title="Sign in" actions={ <> <Button variant="primary">Sign in</Button> <Button variant="ghost">Cancel</Button> </> }> <Input placeholder="Email" /> <Input type="password" placeholder="Password" /></Card>Compact + bordered
Section titled “Compact + bordered”Flat & dense
Less padding, stronger border, no shadow.
Flat & dense
Less padding, stronger border, no shadow.
<div class="card card-compact card-bordered"> <div class="card-body"> <h3 class="card-title">Flat & dense</h3> <p class="card-description">Less padding, stronger border, no shadow.</p> </div></div><Card compact bordered title="Flat & dense" description="Less padding, stronger border, no shadow."/>Color variants
Section titled “Color variants”Muted
Sits flush with the page background.
Primary
A highlighted, featured card.
Info
Neutral, informational context.
Success
All systems operational.
Warning
Approaching the rate limit.
Danger
Deleting this is irreversible.
Muted
Sits flush with the page background.
Primary
A highlighted, featured card.
Info
Neutral, informational context.
Success
All systems operational.
Warning
Approaching the rate limit.
Danger
Deleting this is irreversible.
<div class="card card-muted"> <div class="card-body"> <h3 class="card-title">Muted</h3> <p class="card-description">Sits flush with the page background.</p> </div></div><div class="card card-primary"> <div class="card-body"> <h3 class="card-title">Primary</h3> <p class="card-description">A highlighted, featured card.</p> </div></div><div class="card card-info"> <div class="card-body"> <h3 class="card-title">Info</h3> <p class="card-description">Neutral, informational context.</p> </div></div><div class="card card-success"> <div class="card-body"> <h3 class="card-title">Success</h3> <p class="card-description">All systems operational.</p> </div></div><div class="card card-warning"> <div class="card-body"> <h3 class="card-title">Warning</h3> <p class="card-description">Approaching the rate limit.</p> </div></div><div class="card card-danger"> <div class="card-body"> <h3 class="card-title">Danger</h3> <p class="card-description">Deleting this is irreversible.</p> </div></div><> <Card variant="muted" title="Muted" description="Sits flush with the page background." /> <Card variant="primary" title="Primary" description="A highlighted, featured card." /> <Card variant="info" title="Info" description="Neutral, informational context." /> <Card variant="success" title="Success" description="All systems operational." /> <Card variant="warning" title="Warning" description="Approaching the rate limit." /> <Card variant="danger" title="Danger" description="Deleting this is irreversible." /></>With icon
Section titled “With icon”Today's orders
128 placed, 14 awaiting fulfilment.
Today's orders
128 placed, 14 awaiting fulfilment.
<div class="card card-bordered"> <div class="card-body"> <h3 class="card-title"> <i class="ti ti-shopping-bag" aria-hidden="true"></i> Today's orders </h3> <p class="card-description">128 placed, 14 awaiting fulfilment.</p> <div class="card-actions"> <button class="btn btn-primary btn-sm"> Open queue <i class="ti ti-arrow-right" aria-hidden="true"></i> </button> </div> </div></div><Card bordered icon={IconShoppingBag} title="Today's orders" description="128 placed, 14 awaiting fulfilment." actions={ <Button variant="primary" size="sm" iconTrailing={IconArrowRight}> Open queue </Button> }/>Header toolbar
Section titled “Header toolbar”Webhook
Fires on every order status change.
Webhook
Fires on every order status change.
<div class="card card-bordered"> <div class="card-body"> <div class="card-header"> <h3 class="card-title">Webhook</h3> <div class="card-toolbar"> <button class="btn btn-ghost btn-square btn-sm" type="button" aria-label="Edit" > <i class="ti ti-pencil" aria-hidden="true"></i> </button> <button class="btn btn-ghost btn-square btn-sm" type="button" aria-label="Dismiss" > <i class="ti ti-x" aria-hidden="true"></i> </button> </div> </div> <p class="card-description">Fires on every order status change.</p> </div></div><Card bordered title="Webhook" description="Fires on every order status change." toolbar={ <> <Button variant="ghost" size="sm" icon={IconPencil} aria-label="Edit" /> <Button variant="ghost" size="sm" icon={IconX} aria-label="Dismiss" /> </> }/>Storefront
Live since March, 1.2k monthly orders.
Storefront
Live since March, 1.2k monthly orders.
<div class="card card-bordered" style="max-width: 20rem"> <div class="card-media"> <img src="https://picsum.photos/seed/orders/640/360" alt="" style="aspect-ratio: 16 / 9" /> </div> <div class="card-body"> <h3 class="card-title">Storefront</h3> <p class="card-description">Live since March, 1.2k monthly orders.</p> </div></div><Card bordered style={{ maxWidth: "20rem" }} media={ <img src="https://picsum.photos/seed/orders/640/360" alt="" style={{ aspectRatio: "16 / 9" }} /> } title="Storefront" description="Live since March, 1.2k monthly orders."/>Per-slot styling React only
Section titled “Per-slot styling ”Deploy failed
Build #2042 exited with code 1.
<Card bordered title="Deploy failed" description="Build #2042 exited with code 1." classNames={{ title: "text-danger", description: "font-mono" }}/>Two bodies, composed
Section titled “Two bodies, composed”Connected
Last sync 3 minutes ago.
Connected
Last sync 3 minutes ago.
<div class="card card-bordered"> <div class="card-body" style="border-bottom: 1px solid var(--color-border)"> <h3 class="card-title">Connected</h3> <p class="card-description">Last sync 3 minutes ago.</p> </div> <div class="card-body"> <div class="card-actions"> <button class="btn btn-ghost btn-sm">Re-sync now</button> <button class="btn btn-danger btn-sm">Disconnect</button> </div> </div></div><Card.Container bordered> <Card.Body style={{ borderBottom: "1px solid var(--color-border)" }}> <Card.Title>Connected</Card.Title> <Card.Description>Last sync 3 minutes ago.</Card.Description> </Card.Body> <Card.Body> <Card.Actions> <Button variant="ghost" size="sm"> Re-sync now </Button> <Button variant="danger" size="sm"> Disconnect </Button> </Card.Actions> </Card.Body></Card.Container>Scroll region
Section titled “Scroll region”Activity
Order #1024 placed
Order #1023 refunded
Order #1022 shipped
Order #1021 placed
Order #1020 placed
Order #1019 cancelled
Order #1018 shipped
Activity
Order #1024 placed
Order #1023 refunded
Order #1022 shipped
Order #1021 placed
Order #1020 placed
Order #1019 cancelled
Order #1018 shipped
<div class="card card-bordered card-scroll" style="height: 14rem"> <div class="card-header"> <h3 class="card-title">Activity</h3> </div> <div class="card-body"> <p>Order #1024 placed</p> <p>Order #1023 refunded</p> <p>Order #1022 shipped</p> <p>Order #1021 placed</p> <p>Order #1020 placed</p> <p>Order #1019 cancelled</p> <p>Order #1018 shipped</p> </div> <div class="card-actions"> <button class="btn btn-ghost btn-sm">View all</button> </div></div><Card.Container bordered scroll style={{ height: "14rem" }}> <Card.Header> <Card.Title>Activity</Card.Title> </Card.Header> <Card.Body> <p>Order #1024 placed</p> <p>Order #1023 refunded</p> <p>Order #1022 shipped</p> <p>Order #1021 placed</p> <p>Order #1020 placed</p> <p>Order #1019 cancelled</p> <p>Order #1018 shipped</p> </Card.Body> <Card.Actions> <Button variant="ghost" size="sm"> View all </Button> </Card.Actions></Card.Container>Reference
Section titled “Reference”| Part | Renders | Class |
|---|---|---|
Card |
<div> |
card |
Card.Container |
<div> |
card |
Card.Media |
<div> |
card-media |
Card.Body |
<div> |
card-body |
Card.Header |
<div> |
card-header |
Card.Toolbar |
<div> |
card-toolbar |
Card.Title |
<h3> |
card-title |
Card.Description |
<p> |
card-description |
Card.Actions |
<div> |
card-actions |
| Part | Prop | Type | Default |
|---|---|---|---|
Card |
variant |
"default" | "muted" | "primary" | "info" | "success" | "warning" | "danger" |
"default" |
Card |
bordered |
boolean |
false |
Card |
compact |
boolean |
false |
Card |
scroll |
boolean |
false |
Card |
media |
ReactNode |
— |
Card |
icon |
IconProp |
— |
Card |
title |
ReactNode |
— |
Card |
description |
ReactNode |
— |
Card |
toolbar |
ReactNode |
— |
Card |
actions |
ReactNode |
— |
Card |
classNames |
slots | — |
Card.Title |
icon |
IconProp |
— |
Card always wraps its children in a Card.Body and renders the shorthand props around them: media above, then title (with icon, plus toolbar in a Card.Header when present), description, children, actions. classNames covers media, body, header, toolbar, title, description, actions.
variant, bordered, compact and scroll live on the root, so they work on Card.Container too — which is the form to reach for when the layout doesn’t fit one body: two bodies, a custom divider, a media header, or a scroll region. Card.Title keeps its icon prop there, and Card.Header + Card.Toolbar are available for building the header row by hand.
toolbar controls are usually square icon buttons with an aria-label. Plus native <div> attributes.
Vanilla
Section titled “Vanilla”| Class | Effect |
|---|---|
card |
Column panel: surface-muted fill, 1px border, 0.75rem radius, extra-small shadow |
card-body |
Content region: 1.25rem padding, 0.75rem gap |
card-title |
text-lg semibold row, 0.5rem gap for a leading icon |
card-header |
Title row that can hold a trailing toolbar |
card-toolbar |
Trailing controls pushed to the row end; icons render at 1.25rem |
card-description |
text-sm muted |
card-actions |
Wrapping button row pinned to the bottom of the body, 0.5rem gap |
card-media |
Full-bleed media block; inherits the card’s radius at the first or last position |
card-compact |
Body drops to 0.75rem padding, 0.5rem gap |
card-bordered |
No shadow, stronger border |
card-muted |
Fills with the page surface so the panel sits flush rather than raised |
card-primary card-info card-success card-danger |
Tinted -muted surface and border, title in the matching accent |
card-warning |
Tinted warning surface and border — title keeps the default colour |
card-scroll |
Pins a direct-child card-header and card-actions, giving each padding and a divider, and scrolls the body |
There is no card-default — it’s the unmodified card. card-warning is the one variant whose title isn’t accented: yellow on the muted yellow surface fails contrast, as noted in Conventions › Tones.
A tinted surface signals status, so it reads as noise when every panel has one. The default card sits one step above the page; card-muted sits flush with it and carries no status meaning at all, which makes it the one to reach for when grouping or de-emphasising.
Size the media element yourself — aspect-ratio on the <img> is usually what you want, since the wrapper has no intrinsic height. card-scroll needs an explicit height on the card, and only pins a header and actions that are direct children; inside a card-body they carry no padding of their own.
For a single metric rather than a panel, use a stat card.