Card
A raised surface: border, radius, padding and elevation, and nothing else. The smallest component of the kit, and the one meant to be built on.
API
Props
| prop | type | default | |
|---|---|---|---|
as? | ElementType | "div" | the element or component to render |
className? | string | — | merged over the defaults, so it wins |
…rest | props of as | — | typed against the chosen element |
Examples
Usage
A Card is a surface and nothing else: border, radius, padding, background, elevation. What goes inside is your markup, laid out however that content needs.
<Card>
<h3>Invoice 0142</h3>
<p>Issued on 4 August</p>
</Card>Invoice 0142
Issued on 4 August
Invoice 0143
As a control
The focus styles ship with the component — the gradient border on focus, an outline on focus-visible — but a div cannot take focus, so they only appear once the card is something that can. When the whole card is clickable, render it as the thing it actually is instead of attaching a click handler to a box.
<Card as={Link} to="/invoices/142" tabIndex={0}>
<h3>Invoice 0142</h3>
</Card>Media and edge to edge
className is merged over the base classes rather than appended, so an override genuinely replaces what it contradicts: dropping the padding does not need a more specific selector, just p-0. Add overflow-hidden and the content is clipped to the radius.
<Card className="p-0 overflow-hidden">
<img src={cover} alt="" />
<div className="p-5">…</div>
</Card>Cover
p-0 plus overflow-hidden
A tighter padding
<Card className="p-0 overflow-hidden">
<img src={cover} alt="" />
</Card>Details
A surface, not a layout
Card has no header slot, no footer slot and no title prop. The reason is that card layouts differ far more than card surfaces do: a component with fixed slots would be right for one screen and in the way on the next, whereas the surface — the thing that makes it read as a card at all — is the same everywhere.
It also keeps the component honest about what it costs. Everything you see in a card is markup you wrote, so there is never a hidden wrapper to fight when the design changes.
Composing with the decorators
Because it is a single element with a radius, Card is the natural child of the glow decorators: the pseudo-elements inherit its border-radius, so the light follows the rounded corners instead of cutting across them.
<BorderGlow>
<Card className="margo-col-span-4">…</Card>
</BorderGlow>On a grid, keep the placement on the Card itself — the decorator clones it rather than wrapping it, so the column utilities belong to the card and nothing is inserted between the grid and its item.
A card that is a control
Both are reachable with the keyboard and announced for what they are — a link that navigates, a button that acts — which a div with an onClick would not be.