Stat

Part of the extras bundle, not included by default.

Intent

A stat is a recognizable shape: small label, big number, short caption underneath. The number is the visual anchor; everything else is supporting context. brio gives the shape typography slots for each line (.stat-label, .stat-value, .stat-description) and a compact variant for dense dashboards. The trend indicator pairs naturally in the description slot.

The slot classes earn their place: each combines font size, weight, color, and line height in ways the existing utilities don't cleanly express. .stat-value in particular needs line-height: 1 and tight letter-spacing to sit cleanly above the label without optical drift.

Basic usage

Revenue $12,450 +12.5% vs last month
<div class="stat">
    <span class="stat-label">Revenue</span>
    <span class="stat-value">$12,450</span>
    <span class="stat-description">
        <span class="trend is-up">+12.5%</span> vs last month
    </span>
</div>

Grid of stat cards

Stats compose with .card and .grid for the dashboard summary shape -- one stat per card, auto-fitting columns based on viewport width.

Revenue $12,450 +12.5% vs last month
Open issues 37 -8 from last week
Uptime 99.98% 0.0% change
<div class="grid" style="--grid-min: 14rem">
    <div class="card">
        <div class="stat">
            <span class="stat-label">Revenue</span>
            <span class="stat-value">$12,450</span>
            <span class="stat-description">
                <span class="trend is-up">+12.5%</span> vs last month
            </span>
        </div>
    </div>
    <div class="card">
        <div class="stat">
            <span class="stat-label">Open issues</span>
            <span class="stat-value">37</span>
            <span class="stat-description">
                <span class="trend is-down">-8</span> from last week
            </span>
        </div>
    </div>
    <div class="card">
        <div class="stat">
            <span class="stat-label">Uptime</span>
            <span class="stat-value">99.98%</span>
            <span class="stat-description">
                <span class="trend is-neutral">0.0%</span> change
            </span>
        </div>
    </div>
</div>

Compact

.is-compact drops the value to --step-2 and tightens the gap. For dense dashboard tiles or KPI rows where a full-size stat would dominate.

Users 1,204
Sessions 3,891
Bounce rate 24.3%
<div class="grid" style="--grid-min: 10rem">
    <div class="stat is-compact">
        <span class="stat-label">Users</span>
        <span class="stat-value">1,204</span>
    </div>
    <div class="stat is-compact">
        <span class="stat-label">Sessions</span>
        <span class="stat-value">3,891</span>
    </div>
    <div class="stat is-compact">
        <span class="stat-label">Bounce rate</span>
        <span class="stat-value">24.3%</span>
    </div>
</div>

Minimal -- without trend

The description slot is freeform; trends are one common occupant but plain supporting text works too.

Open issues 37 4 critical, 12 in review
<div class="stat">
    <span class="stat-label">Open issues</span>
    <span class="stat-value">37</span>
    <span class="stat-description">4 critical, 12 in review</span>
</div>

Semantic markup with <dl>

A description list (<dl> + <dt> + <dd>) makes the label-value relationship explicit to assistive tech. brio's slot classes work on either markup; reach for <dl> in data-heavy contexts where the semantic relationship matters (financial summaries, audit reports, compliance dashboards).

Revenue
$12,450
+12.5% vs last month
<dl class="stat">
    <dt class="stat-label">Revenue</dt>
    <dd class="stat-value">$12,450</dd>
    <dd class="stat-description">
        <span class="trend is-up">+12.5%</span> vs last month
    </dd>
</dl>

Brio resets <dl>'s default margin and <dd>'s indent inside .stat so the grid layout takes over cleanly.

Customization

Gap, label / value / description sizes, label color, and value color all flow through scoped --stat-* tokens. The value defaults to a fluid --step-3 so the metric scales with viewport -- override to --step-2 or --step-4 on individual instances when the surrounding card sets a different rhythm. Label and description default to --step--1; same fluid scale, smaller tier.

Accessibility

  • Plain <span> markup is the default; switch to <dl> when you want the label-value relationship announced as such by assistive tech.
  • Don't use heading tags (<h2>, <h3>) for the value -- it would pollute the document outline. The value is a metric, not a section heading.
  • When pairing with trend, carry the direction in the textual sign (+, -), not the color alone. Color isn't reliable for screen readers or users with color-vision differences.

Markup

<!-- Default -->
<div class="stat">
    <span class="stat-label">Revenue</span>
    <span class="stat-value">$12,450</span>
    <span class="stat-description">
        <span class="trend is-up">+12.5%</span> vs last month
    </span>
</div>

<!-- Compact -->
<div class="stat is-compact">
    <span class="stat-label">Open issues</span>
    <span class="stat-value">37</span>
</div>

<!-- Description-list semantics -->
<dl class="stat">
    <dt class="stat-label">Revenue</dt>
    <dd class="stat-value">$12,450</dd>
    <dd class="stat-description">...</dd>
</dl>

CSS Reference: Stat

Metric display with label, value, and optional description

Source: src/css/extras/stat.css

Tokens

TokenDefaultDescription
--stat-gapvar(--gap-tight)Gap between the label, value, and description slots
--stat-label-sizevar(--step--1)Font size for the metric label
--stat-value-sizevar(--step-3)Font size for the big number
--stat-description-sizevar(--step--1)Font size for the supplementary description
--stat-label-colorvar(--color-text-muted)Text color for the label
--stat-value-colorvar(--color-text)Text color for the value

Slots

SlotDescription
& .stat-labelLabel text identifying the metric
& .stat-valueLarge number or formatted value
& .stat-descriptionSupplementary text or trend indicator

Classes

ClassDescription
.statcomponent root
.is-compactTighter layout with smaller value for dense dashboard cards