Component Porchlight CSS

Card

A raised surface grouping related content - header, body, and optional footer, with a container-query header and an interactive variant.

52 components 51 stable 1 experimental

Command

Search Porchlight

Card

The .c-card is a raised surface for grouping related content - the workhorse of SaaS dashboards (KPI tiles, list items, settings sections, detail panels).

Elevation comes from a soft shadow, not a heavy bg contrast - surface is intentionally close to bg; the border + shadow define the card.

Semantic HTML

<section class="c-card">
  <header class="c-card__header">
    <h2 class="c-card__title">Quarterly usage</h2>
    <button class="c-button" data-variant="ghost">Export</button>
  </header>
  <div class="c-card__body">...</div>
</section>

Interactive (clickable) cards

Add data-interactive or use an <a class="c-card"> for a hover lift + focus ring - for navigation tiles and selectable list items.

<a class="c-card" href="/accounts/acme">
  <header class="c-card__header">
    <h2 class="c-card__title">Acme Ops</h2>
  </header>
  <div class="c-card__body">Enterprise · $2,400/mo</div>
</a>

App surfaces

Add data-surface="app" for tighter operational surfaces inside dense desktop app shells. It keeps the same border, elevation, spacing, and semantics, but uses the smaller large-surface radius so dashboard cards do not feel overly soft.

<section class="c-card" data-surface="app">
  <header class="c-card__header">
    <h2 class="c-card__title">Queue health</h2>
  </header>
  <div class="c-card__body">23 jobs waiting</div>
</section>

Class contract

SelectorRole
.c-cardThe card (<section> or <a> if interactive).
.c-card__headerTitle + optional action row.
.c-card__titleThe <h2> heading.
.c-card__bodyMain content.
.c-card__footerOptional action row with a top divider.
[data-interactive] / <a>Enables hover lift + focus ring.
[data-surface="app"]Uses a tighter app-shell radius.

Tokens consumed

--pl-color-{surface,border,text,text-muted}, --pl-shadow-{1,2}, --pl-focus-color, --pl-radius-{lg,xl}, --pl-space-{2,3,4,5}, --pl-text-lg, --pl-leading-tight, --pl-duration-2, --pl-ease-standard.

Tokens exposed

TokenDefaultPurpose
--c-card-padding--pl-space-5Inner padding.
--c-card-bg--pl-color-surfaceCard fill.
--c-card-border--pl-color-borderBorder color.
--c-card-shadow--pl-shadow-1Default elevation.
--c-card-radius--pl-radius-xlCorner radius.

Container query

The card establishes container: c-card / inline-size. The header collapses from a row to a column when the card is narrower than 28rem - not the viewport. A card in a narrow split pane stacks even on a wide screen.

Accessibility

  • Semantics: use a real <section> (or <article> for self-contained content). The title should be a heading (<h2><h6> at the right level).
  • Interactive cards: when the card is an <a>, it’s natively focusable and keyboard-activatable. When it’s a <div data-interactive>, you must add tabindex="0" and a role/keyboard handler - prefer the <a> form.
  • Focus: interactive cards draw a crisp focus ring + elevated shadow.