Card
A frame around a group of content: a tinted panel on the page, a raised item such as a card on a board, or a ghost row that leads somewhere, such as a link to a settings page. It frames, and lays nothing out: what's inside keeps its own layout.
Installation
bun add @harmo-ui/css @harmo-ui/reactnpm install @harmo-ui/css @harmo-ui/reactpnpm add @harmo-ui/css @harmo-ui/reactyarn add @harmo-ui/css @harmo-ui/reactbunx harmo-ui add cardnpx harmo-ui add cardpnpm dlx harmo-ui add cardyarn dlx harmo-ui add cardUsage
Examples
Default
Tinted, in the page's secondary background, with no border: a panel for a group of content. The card frames it and lays nothing out. Use secondary text or darker on it: tertiary text is 4.4:1 on the tint.
Your trial ends in 12 days. Add a payment method to keep your campaigns running.
<Card>
<p>
Your trial ends in 12 days. Add a payment method to keep your campaigns
running.
</p>
<Button variant="secondary">Add payment method</Button>
</Card><div class="hcard">
<p>
Your trial ends in 12 days. Add a payment method to keep your campaigns
running.
</p>
<button class="hbutton" data-variant="secondary" type="button">
<span class="hbutton-label">Add payment method</span>
</button>
</div>Raised
data-variant="raised": the page's background, with a border and a shadow, for an item that stands apart from what's around it, such as a ticket on a board.
Refund not received for order 1042
Billing<Card variant="raised">
<p>Refund not received for order 1042</p>
<Tag>Billing</Tag>
</Card><div class="hcard" data-variant="raised">
<p>Refund not received for order 1042</p>
<span class="htag">Billing</span>
</div>Ghost
data-variant="ghost": no frame until a link or button card is hovered, for rows that each lead somewhere. The whole card is the link, so its content is its name.
<nav aria-label="Settings">
<a class="hcard" data-variant="ghost" href="#team">Team members</a>
<a class="hcard" data-variant="ghost" href="#billing">Billing</a>
<a class="hcard" data-variant="ghost" href="#developers">Developers</a>
</nav>Padding
16px by default. --harmo-card-padding on a card makes it tighter, as for a compact list.
Last synced 5 minutes ago
<Card style={{ "--harmo-card-padding": "8px" } as CSSProperties}>
<p>Last synced 5 minutes ago</p>
</Card><div class="hcard" style="--harmo-card-padding: 8px">
<p>Last synced 5 minutes ago</p>
</div>API reference
React
<Card> renders a <div>, or with href, a link through your app's link component, as Button does. Other props are the element's attributes. For a card that's a button, put className="hcard" on a <button>.
| Prop | Effect |
|---|---|
variant | raised or ghost |
href | Renders a link |
HTML
Any block element with class="hcard", such as a <div>, <section>, or <article>, or an <a> or <button> for a card that leads somewhere. Load card.css. It needs no script.
| Hook | Effect |
|---|---|
| Default | Tinted: --harmo-color-background-secondary, with no border |
data-variant="raised" | --harmo-color-background, a 1px --harmo-color-border border, and --harmo-box-shadow-sm |
data-variant="ghost" | No background; on a link or button card, --harmo-color-background-hover on hover |
--harmo-card-padding | The padding, 16px by default; set it on a card for a tighter one |
Every variant has an 8px radius and a 1px border, transparent unless raised, so all three are the same size, and forced-colors mode, which drops backgrounds, still draws the frame. The first and last child's own block margins are removed, since the card's padding spaces its content. A link or button card is a block that reads like its content: no underline, the text color around it, and the usual focus ring.
See Card's full contract.
Accessibility
A card is only a frame: give a group a heading, or a <section> with a name, where it needs one, as without a card. A card that leads somewhere is a native link or button, so its whole content is its name: keep it short, such as a title and one line.
On the tint, and on a hovered ghost card, use secondary text or darker: tertiary text is 4.4:1 there, below WCAG AA.