Cards

One card per logical block — the variants

The rules — one card per logical block

  • A card wraps ONE logical block (a list, a form, a summary) — never several unrelated things, never a card inside a card.
  • The header is optional: .card-header with an h3.card-title; a muted annotation rides a span.text-body-secondary.fw-normal INSIDE the title (this page's own headers demonstrate it).
  • Header actions sit right automatically (the header is flex): at most one .btn-sm action or a compact group — a card's PRIMARY action; everything else goes in a dropdown.
  • Cards own their vertical spacing (margin-bottom = the content padding) — never add spacing utilities between stacked cards (the layout standard).
  • Full-bleed content (tables, listers) goes directly in the card, NOT inside .card-body — see tables.
The basic card: just a .card-body. Use it when the block needs no title — the content speaks for itself.

With a header — title + one action

The header is flex: the title sits left, the action right, with no extra markup. The action is the card's primary one — secondary operations belong in a ri-more-2-fill dropdown.

With a footer

A footer holds meta or a link to more — never the card's primary action (that stays in the header).
Active users
1,284
+12%
Failed jobs
7
-3%
  • The stat card is THE dashboard number: .stat-card with .stat-icon on a bg-*-subtle text-*-emphasis pair, .stat-label + .stat-value, optional .stat-change.up/.down.
  • Stat cards come in the four-up stat row (col-12 col-sm-6 col-xl-3) at the top of a dashboard — see the dashboard page.
  • Icon color follows the metric's semantics (the fixed color map), not decoration.