Cards
A card is a bordered region of a screen: a header with its title and actions, a body, a footer. It is a region - the width prefixes inside it measure the card, not the window.
Examples
A card that is a section of the screen is a <section> named by its heading. The header holds an icon, the title and whatever belongs to it; the footer holds the card's actions.
Price
in the base currency THBAdults 2,500 · children 1,900 · under four free.
The visitor's currency is an estimate.
<section class="card" aria-labelledby="card-basic-title">
<div class="card-header"><i class="bi bi-cash-coin" aria-hidden="true"></i><h2 id="card-basic-title">Price</h2><span class="text-muted fs-12">in the base currency THB</span></div>
<div class="card-body vstack gap-8">
<p>Adults 2,500 · children 1,900 · under four free.</p>
<p class="text-muted">The visitor's currency is an estimate.</p>
</div>
<div class="card-footer justify-content-end">
<button class="btn" type="button">Cancel</button>
<button class="btn btn-primary" type="button">Save</button>
</div>
</section>A product tints the head of every card with --redz-card-header-bg.
Images
card-img-top and card-img-bottom round the image with the card's corners; card-img-overlay lays the card's words over a card-img. A stretched-link makes the whole card its link.
North Bay by speedboat
From 2 500 THB · a day
<div class="grid md:cols-2 gap-16">
<section class="card" aria-labelledby="card-images-title">
<img class="card-img-top ratio-16x9" src="img/lagoon.svg" alt="A lagoon under green hills">
<div class="card-body vstack gap-4">
<h2 class="fs-16" id="card-images-title"><a class="stretched-link" href="#card-images">North Bay by speedboat</a></h2>
<p class="text-muted mb-0">From 2 500 THB · a day</p>
</div>
</section>
<section class="card" aria-labelledby="card-overlay-title">
<img class="card-img ratio-16x9" src="img/lagoon.svg" alt="">
<div class="card-img-overlay vstack justify-content-end">
<h2 class="fs-16" id="card-overlay-title">The emerald lake</h2>
</div>
</section>
</div>Tabs on a card
A nav placed straight in the card lines up with the header's padding.
North Bay
A day at sea: snorkelling at two reefs, lunch on the boat.
Adults 2,500 · children 1,900.
<section class="card" aria-labelledby="card-tabs-title">
<div class="card-header"><h2 id="card-tabs-title">North Bay</h2></div>
<div class="nav nav-underline" role="tablist" aria-label="North Bay">
<button class="nav-link" type="button" role="tab" id="card-tabs-1" aria-selected="true" aria-controls="card-tabs-panel-1">Details</button>
<button class="nav-link" type="button" role="tab" id="card-tabs-2" aria-selected="false" aria-controls="card-tabs-panel-2">Prices</button>
</div>
<div class="card-body" id="card-tabs-panel-1" role="tabpanel" aria-labelledby="card-tabs-1" tabindex="0"><p>A day at sea: snorkelling at two reefs, lunch on the boat.</p></div>
<div class="card-body" id="card-tabs-panel-2" role="tabpanel" aria-labelledby="card-tabs-2" tabindex="0" hidden><p>Adults 2,500 · children 1,900.</p></div>
</section>A grid of cards
The parent sets the grid; each card measures itself. Under 576 px of the region the cards stack.
Bookings
128
this week
Revenue
312,400 THB
this week
<div class="grid sm:cols-2 gap-16">
<section class="card" aria-labelledby="card-grid-a"><div class="card-header"><h2 id="card-grid-a">Bookings</h2></div><div class="card-body"><p class="fs-24 fw-600 tabular-nums">128</p><p class="text-muted">this week</p></div></section>
<section class="card" aria-labelledby="card-grid-b"><div class="card-header"><h2 id="card-grid-b">Revenue</h2></div><div class="card-body"><p class="fs-24 fw-600 tabular-nums">312,400 THB</p><p class="text-muted">this week</p></div></section>
</div>A body that scrolls
card-scroll with a height - max-h-*, from 160 to 640 px - keeps the card's header and footer in view and scrolls its body between them, as a dialog does: a list of tickets, a thread above its reply box.
Tickets
<section class="card card-scroll max-h-240" aria-labelledby="card-scrolling-title">
<div class="card-header"><h2 id="card-scrolling-title">Tickets</h2></div>
<div class="card-body" tabindex="0" role="region" aria-labelledby="card-scrolling-title">
<div class="list-group list-group-flush">
<button class="list-group-item list-group-item-action" type="button" aria-current="true">The booking page shows the wrong price</button>
<button class="list-group-item list-group-item-action" type="button">A new language for the site</button>
<button class="list-group-item list-group-item-action" type="button">The invoice for October</button>
<button class="list-group-item list-group-item-action" type="button">Photos do not upload from a phone</button>
<button class="list-group-item list-group-item-action" type="button">Change the site's address</button>
<button class="list-group-item list-group-item-action" type="button">Two owners for one site</button>
</div>
</div>
<div class="card-footer"><button class="btn btn-sm" type="button"><i class="bi bi-plus-lg" aria-hidden="true"></i>New ticket</button></div>
</section>A state on its edge
The utility edge-top-{tone} draws a 3 px line of a state on a card's top edge, instead of coloring its frame; edge-start-{tone} does it on the start edge of a row. The words still say the state.
Dispatcher
Running, last beat 4 s ago
Mail queue
Late by 6 minutes
- Online bookingCalendar, deposits, reminders490 THB
- Site and hostingIncluded in every planIncluded
<div class="grid sm:cols-2 gap-16">
<section class="card edge-top-success" aria-labelledby="card-edge-a"><div class="card-header"><h2 id="card-edge-a">Dispatcher</h2></div><div class="card-body"><p>Running, last beat 4 s ago</p></div></section>
<section class="card edge-top-warning" aria-labelledby="card-edge-b"><div class="card-header"><h2 id="card-edge-b">Mail queue</h2></div><div class="card-body"><p>Late by 6 minutes</p></div></section>
</div>
<ul class="list-group" aria-label="Plan items">
<li class="list-group-item hstack gap-12 edge-start-primary"><span>Online booking<span class="d-block fs-12 text-muted">Calendar, deposits, reminders</span></span><span class="ms-auto tabular-nums">490 THB</span></li>
<li class="list-group-item hstack gap-12 edge-start-success bg-page"><span>Site and hosting<span class="d-block fs-12 text-muted">Included in every plan</span></span><span class="ms-auto text-muted">Included</span></li>
</ul>For a category instead of a state - a site, a team, a kind of job - edge-top-chart-1 to -8 and edge-start-chart-1 to -8 take the charts' eight colors, so a row matches its series in a chart.
- Main Island
- South Bay
- West Bay
<ul class="list-group" aria-label="Sites">
<li class="list-group-item edge-start-chart-1">Main Island</li>
<li class="list-group-item edge-start-chart-2">South Bay</li>
<li class="list-group-item edge-start-chart-3">West Bay</li>
</ul>Accessibility
- A card that is a part of the page is a
<section>witharia-labelledbypointing at its heading; a card in a list of cards is an<article>or a list item. - A card has no outer margin: the gap between cards belongs to their parent.
- A card being refreshed in place turns busy with
REDZ.ui.busy(card, promise)- see Busy.
Tokens
From css/components/card.css, which declares no custom property of its own.
It reads the theme's --redz-border, --redz-radius-12, --redz-bg, --redz-space-16, --redz-space-8, --redz-space-12, --redz-card-header-bg, --redz-text-muted.
From Bootstrap 5.3
| Bootstrap 5.3 | REDZ.UI | Change | Note |
|---|---|---|---|
card-group | - | review | grid with gap-16 |
card-header-pills | - | review | a nav straight in the card |
card-header-tabs | - | review | a nav straight in the card |
card-link | - | review | a heading and paragraphs in card-body |
card-subtitle | - | review | a heading and paragraphs in card-body |
card-text | - | review | a heading and paragraphs in card-body |
card-title | - | review | a heading and paragraphs in card-body |