Skip to content

Cards

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>

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>

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>

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>

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>

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>

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>

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" }}
/>

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>

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>
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.

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.