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/react

Usage

import { Card } from "@harmo-ui/react";

<Card>
  <p>Your trial ends in 12 days.</p>
</Card>

<Card variant="raised">
  <p>Refund not received for order 1042</p>
</Card>

<Card variant="ghost" href="/settings/team">
  Team members
</Card>

Examples

This site is using your theme

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>

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>

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">
  <Card variant="ghost" href="#team">
    Team members
  </Card>
  <Card variant="ghost" href="#billing">
    Billing
  </Card>
  <Card variant="ghost" href="#developers">
    Developers
  </Card>
</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>

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

PropEffect
variantraised or ghost
hrefRenders 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.

HookEffect
DefaultTinted: --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-paddingThe 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.