Card
Create account
Enter your details below.
<div class="card"> <div class="card-header"> <h3 class="card-title">Create account</h3> <p class="card-description">Enter your details below.</p> </div> <div class="card-content"> <div class="field"> <label class="label" for="card-email">Email</label> <input class="input" id="card-email" type="email" placeholder="you@example.com" /> </div> </div> <div class="card-footer"> <button class="btn btn-ghost">Cancel</button> <button class="btn">Create</button> </div></div><div class="card"> <div class="card-header"> <h3 class="card-title">Title</h3> <p class="card-description">Supporting line.</p> </div> <div class="card-content">…</div> <div class="card-footer">…</div></div>Composition
Section titled “Composition”Billing
Next invoice on 1 September.
Pro plan · $20 per month
<div class="card"> <div class="card-header"> <h3 class="card-title">Billing</h3> <p class="card-description">Next invoice on 1 September.</p> <div class="card-action"> <button class="btn btn-ghost btn-sm">Manage</button> </div> </div> <div class="card-content"> <p class="card-description">Pro plan · $20 per month</p> </div> <div class="card-footer"> <button class="btn btn-outline btn-sm">Download invoice</button> </div></div>| Class | Part |
|---|---|
.card | Container |
.card-header | Title area |
.card-title | Heading |
.card-description | Supporting line |
.card-action | Control pinned to the header’s trailing edge |
.card-content | Body |
.card-footer | A bar across the bottom, with its own surface |
The footer is not just a row: it takes the card’s full width, carries a top border and a muted surface, and the card drops its own bottom padding to make room. The same happens for an image at either end.
Default
Roomier spacing throughout.
Body content.
Small
One variable tightens every section.
Body content.
<div class="card"> <div class="card-header"> <h3 class="card-title">Default</h3> <p class="card-description">Roomier spacing throughout.</p> </div> <div class="card-content"> <p class="card-description">Body content.</p> </div></div>
<div class="card" data-size="sm"> <div class="card-header"> <h3 class="card-title">Small</h3> <p class="card-description">One variable tightens every section.</p> </div> <div class="card-content"> <p class="card-description">Body content.</p> </div></div>data-size="sm" lowers --card-spacing, and every section follows: padding, gaps and the space
between header, content and footer. The title steps down a size with it.
Spacing
Section titled “Spacing”Nothing stops you setting the variable yourself, for a card that has to match a layout the two presets do not.
Roomier
One variable moves every section at once.
Set --card-spacing to whatever the layout needs.
<div class="card" style="--card-spacing: 1.5rem"> <div class="card-header"> <h3 class="card-title">Roomier</h3> <p class="card-description">One variable moves every section at once.</p> </div> <div class="card-content"> <p class="card-description">Set --card-spacing to whatever the layout needs.</p> </div></div><div class="card" style="--card-spacing: 1.5rem">An img as the first or last child runs edge to edge and takes the card’s corners.
Aurora
An image at the top runs to the edge.
<div class="card"> <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 160'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%236366f1'/%3E%3Cstop offset='1' stop-color='%23ec4899'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='400' height='160' fill='url(%23g)'/%3E%3C/svg%3E" alt="" width="400" height="160" /> <div class="card-header"> <h3 class="card-title">Aurora</h3> <p class="card-description">An image at the top runs to the edge.</p> </div> <div class="card-footer"> <button class="btn btn-sm">Open</button> </div></div>Give a decorative image alt="" so it is skipped, and set width and height so the card does
not jump when it loads.
The card is a plain container, so it takes any element — a <form> here, and the footer’s submit
button posts without extra wiring.
<form class="card"> <div class="card-header"> <h3 class="card-title">Create account</h3> <p class="card-description">Enter your details below.</p> </div> <div class="card-content"> <div class="field-group"> <div class="field"> <label class="label" for="card-form-email">Email</label> <input class="input" id="card-form-email" type="email" placeholder="you@example.com" /> </div> <div class="field"> <label class="label" for="card-form-password">Password</label> <input class="input" id="card-form-password" type="password" /> </div> </div> </div> <div class="card-footer"> <button class="btn" type="submit">Create</button> </div></form>Set dir="rtl" on the page or on any subtree — padding, corners and positions follow the reading
direction on their own. See the button page for a live example.
Accessibility
Section titled “Accessibility”A card is a container, not a landmark: it has no role of its own, and the heading inside it is what gives it a name in a document outline. Use a real heading level that fits the page rather than picking one for its size.
If the whole card is a link, wrap the heading in the anchor rather than the card — a link the size of a card is hard to escape with a screen reader, and it swallows any control inside it.