Card
A raised sheet whose parts follow the room the card is given.
On this page
A card is a raised sheet with a small structure: media, a header, a body and a footer of actions. Use .card on an <article>, a <section> or a list item. The card is a size container, so its parts follow the room the card is given rather than the viewport: the same markup works in a sidebar, a grid and a full-width column.
Card
<article class="card max-w(320) mx-auto"> <img class="card-media" src="/demo/moonstone.svg" alt> <header class="card-header"> <h3 class="card-title">Atlas</h3> <p class="card-description">atlas.dev · Deployed 2 hours ago</p> <span class="badge badge-success badge-dot card-action">Ready</span> </header> <footer class="card-footer"> <button type="button" class="btn btn-sm">Logs</button> <button type="button" class="btn btn-sm btn-primary">Visit</button> </footer></article>#Parts
Every part is optional, and the card spaces whichever are present by 1rem.
card-mediais an image or a video at the top. It sits 4px inside the card, with a corner 4px smaller than the card's so the two stay concentric, and takes a faint inward outline so a pale image keeps its edge.card-headerholds acard-title, acard-descriptionand, at its end, acard-action: a status, a menu button or a switch.card-bodyis free content.card-footerlines up actions at the end, the main one last.
Parts
<section class="card max-w(380) mx-auto"> <header class="card-header"> <h3 class="card-title">Preview deployments</h3> <p class="card-description">Every pull request gets its own URL.</p> <input type="checkbox" role="switch" class="switch card-action" checked aria-label="Preview deployments"> </header> <div class="card-body"> <label class="field">Branch pattern <input class="input" value="feature/*"> </label> </div> <footer class="card-footer"> <button type="button" class="btn btn-sm">Reset</button> <button type="button" class="btn btn-sm btn-primary">Save</button> </footer></section>#It follows its container
The card declares container: card / inline-size and its parts query it. Queries measure the card's content box, inside its padding:
- Under 15rem, the
card-actionmoves below the title and description, and the footer's buttons stack at full width with the main one first. card-splitsets the media beside the content from 28rem, 4px inside the card on three sides, and stacks it on top below that.
Drag the handle to narrow the preview: the layout changes with the card, not with the window.
Split card
<article class="card card-split"> <img class="card-media" src="/demo/moonstone.svg" alt> <header class="card-header"> <h3 class="card-title">Moonstone and obsidian</h3> <p class="card-description">One material language in light and dark.</p> <span class="badge card-action">Guide</span> </header> <div class="card-body">Every surface is a step on one ladder, lit from above. Edges are half-pixel contours and short shadows that fade.</div> <footer class="card-footer"> <button type="button" class="btn btn-sm">Later</button> <button type="button" class="btn btn-sm btn-primary">Read the guide</button> </footer></article>Because the card is a size container, its width must come from its context: a grid track, a flex item with a basis, or a block. In a shrink-to-fit context such as inline-flex, give it a width.
#Flat
card-flat keeps one contour and no lift, for cards in a dense list or on a tray.
Flat
<div class="tray grid grid-cols(2) gap(4)"> <article class="card card-flat"> <header class="card-header"> <h3 class="card-title">Requests</h3> <p class="card-description">Last 24 hours</p> </header> <div class="card-body text-md fg-text-strong">1.28M</div> </article> <article class="card card-flat"> <header class="card-header"> <h3 class="card-title">Errors</h3> <p class="card-description">Last 24 hours</p> </header> <div class="card-body text-md fg-text-strong">0.02%</div> </article></div>#Interactive
When the whole card is one link or one button, put card and card-interactive on the <a> or <button> itself. It lifts under the pointer and settles when pressed, as a button does. Do not nest other controls inside it.
Interactive
<a class="card card-interactive" href="#installation"> <span class="card-header"> <span class="card-title">Installation</span> <span class="card-description">Add Master UI to a project.</span> </span></a><a class="card card-interactive" href="#theme"> <span class="card-header"> <span class="card-title">Theme</span> <span class="card-description">Materials, light and tokens.</span> </span></a>#Classes
| Class | Description |
|---|---|
card | The raised sheet and size container; its parts are spaced by 1rem |
card-flat | One contour and no shadow, for cards in a dense list or on a tray. With card |
card-interactive | A card that is one link or button: it lifts under the pointer and sinks when pressed. No other control goes inside it. With card |
card-split | Sets the media beside the content from 28rem of content width, and on top below that. With card |
card-media | An image or video at the top, 4px inside the card, 16 / 9 by default |
card-header | The heading group: a title, a description and an optional action at the end |
card-title | The title, in the header |
card-description | A muted line under the title, in the header |
card-action | A control or a status at the end of the header; under 15rem of content it moves below the text |
card-body | Free content |
card-footer | Actions at the foot, aligned to the end with the main one last; under 15rem of content they stack at full width, the main one first |
#Custom properties
| Property | Default | Description |
|---|---|---|
--card-padding | 1.25rem | Padding around the parts |
--card-radius | var(--radius-surface) | Corner radius |
--card-media-inset | 4px | Space between the media and the card's edge |
--card-split | .4 | Share of the width the media takes in a split card. On card-split |