Badge
A compact label for counts, statuses, and tags.
Default
A bare .badge sits on the neutral interactional fill. Use for non-semantic chips like counts or tags.
<span class="badge">Default</span>Filled intents
Add an intent modifier for a solid filled chip. Each intent ships with its paired -foreground, so a runtime token override recolors the chip and the label together.
<div class="demo-row">
<span class="badge badge--primary">Primary</span>
<span class="badge badge--success">Success</span>
<span class="badge badge--warning">Warning</span>
<span class="badge badge--danger">Danger</span>
<span class="badge badge--info">Info</span>
</div>Soft
Add .badge--soft for a tinted chip. The background mixes the intent at 15% over transparent; the label keeps the solid intent color. Without an intent, soft falls back to a muted neutral chip.
<div class="demo-row">
<span class="badge badge--soft">Default</span>
<span class="badge badge--soft badge--primary">Primary</span>
<span class="badge badge--soft badge--success">Success</span>
<span class="badge badge--soft badge--warning">Warning</span>
<span class="badge badge--soft badge--danger">Danger</span>
<span class="badge badge--soft badge--info">Info</span>
</div>With icon
Drop a direct <svg> or <i> child. The icon picks up the text color and scales to the badge's font size.
<div class="demo-row">
<span class="badge badge--soft badge--success">
<i data-lucide="check"></i>
Active
</span>
<span class="badge badge--soft badge--warning">
<i data-lucide="clock"></i>
Pending
</span>
<span class="badge badge--soft badge--danger">
<i data-lucide="x"></i>
Failed
</span>
<span class="badge badge--primary">
<i data-lucide="star"></i>
Featured
</span>
</div>Loading
Slot a .spinner.spinner--sm in to signal in-flight work. It inherits the badge's text color and shrinks to the badge's font size.
<div class="demo-row">
<span class="badge badge--soft badge--primary">
<span class="spinner spinner--sm" role="status" aria-hidden="true"></span>
Syncing
</span>
<span class="badge badge--soft">
<span class="spinner spinner--sm" role="status" aria-hidden="true"></span>
Loading
</span>
<span class="badge badge--info">
<span class="spinner spinner--sm" role="status" aria-hidden="true"></span>
Uploading
</span>
</div>In buttons
Drop a badge inside a button for a count or status.
<div class="demo-row">
<button type="button" class="btn btn--primary">
Inbox
<span class="badge">4</span>
</button>
<button type="button" class="btn btn--outline btn--neutral">
Notifications
<span class="badge badge--danger">12</span>
</button>
</div>Customization
Nine variables retune .badge without touching component CSS. Override on .badge itself, on a parent scope, or on :root. The cascade scopes the change.
| Variable | Default | Use |
|---|---|---|
--badge-radius |
9999px | Corner radius (pill; opts out of --st-radius) |
--badge-min-height |
calc(1.375rem * var(--st-density)) | Minimum height; pill adapts to content above this |
--badge-padding-y |
calc(0.125rem * var(--st-density)) | Vertical padding |
--badge-padding-x |
calc(0.5rem * var(--st-density)) | Horizontal padding |
--badge-font-size |
0.75rem | Label size |
--badge-font-weight |
500 | Label weight |
--badge-tone |
var(--st-muted-foreground) | Color source the soft variant tints over; intents reassign this |
--badge-bg |
var(--st-neutral) | Background; intents set the intent color, soft mixes 15% over --badge-tone |
--badge-color |
var(--st-neutral-foreground) | Label color; intents flip to the paired -foreground; soft reads --badge-tone |
Pill is intentional, so the badge opts out of --st-radius. Override --badge-radius per-component if a square chip is genuinely wanted.