Badge
Badges surface a count, short status, or presence indicator on top of another element.
Components · Data display
A badge is a small, saturated marker that surfaces a count, a short status word, or a presence dot — usually anchored to the corner of another element. Namirial badges are built from --nm-badge-* tokens defined in namirial-theme.css, and ship in seven intents and a dot variant.
Overview
A badge draws the eye to a number or a state without demanding a click. It carries very little content — a count, a short label, or nothing at all (the dot variant) — and almost always overlays or sits directly beside the element it describes.
When to use
- To show an unread or pending count (
12unread messages) - To flag a short, glanceable status (
NEW,BETA,LIVE) - To indicate presence or activity without a count — the dot variant (
online,unread,has update)
When not to use
- For removable, text-first labels — use a tag.
- For a longer status message that needs explanation — use an alert or tooltip.
- As a standalone clickable element — a badge never carries its own interaction; wrap the element it's attached to instead.
Anatomy
A badge is a small pill or circle: a saturated fill, a contrasting outline, and centered content. The dot variant strips the content and padding down to a single 8px circle.
Tokens and values that drive each part
| Part | Role | Source |
|---|---|---|
| Fill | Background | --nm-badge-bg |
| Outline | Border | --nm-badge-border (fixed to a surface-contrast color, not per-intent) |
| Content | Label / count color | --nm-badge-fg |
| Container | Shape | border-radius: 999px, min 20×20px (8×8px for --dot) |
Intents
Unlike tags, badges use a saturated (not soft) background so a small chip still reads clearly at a glance.
Seven intents · saturated background + solid label
Text labels
Badges aren't limited to numbers — short, all-caps labels work the same way and are common for feature flags or lifecycle markers.
Keep labels to one short word — the pill doesn't wrap and isn't meant to hold a phrase.
Dot indicators
The nm-badge--dot modifier drops padding and content to an 8px circle — use it to signal presence or an update without a count.
In context
Badges almost always attach to another element — most often absolutely positioned over its top-right corner.
Anchor the parent with position: relative and absolutely position the badge over the corner that reads most naturally for the surface (usually top-right).
Light & dark theme
Badge intents resolve through the same --palette-tag-badge-* primitives the theme layer already remaps per data-theme — no badge-specific dark overrides are needed, the saturated fill and outline just follow the palette.
Both previews are locked — they don't follow the page theme switcher. Toggle the page theme to see the rest of the documentation cascade.
Do & don't
Accessibility
- A badge is decorative-adjacent: it reinforces information that should also exist elsewhere (e.g. a count in an
aria-labelon the parent button, likearia-label="Inbox, 12 unread"). - Never rely on the dot variant's color alone to convey status — pair it with a text label nearby or in an
aria-label, since color alone isn't accessible to all users. - All seven intents meet WCAG 2.2 AA contrast for content-over-fill.
Token reference
| Token | Role |
|---|---|
--nm-badge-bg | Container fill |
--nm-badge-border | Container outline (fixed, not per-intent) |
--nm-badge-fg | Content color |
Each nm-badge--{intent} modifier reassigns --nm-badge-bg and --nm-badge-fg. {intent} = primary · secondary · accent · info · positive · negative · warning.
Index palette — categorical colors beyond the 7 intents
The same 10-hue categorical palette documented on the Tag page is available for badges: --palette-index-{'{n}'}-50 (soft), -75 (mid), and -100 (solid), for {'{n}'} = 1–10 — fixed hex values that don't remap per theme. There's no dedicated nm-badge--index-{'{n}'} modifier class, so wire them up per instance:
<span class="nm-badge" style="
--nm-badge-bg: var(--palette-index-3-50);
--nm-badge-border: var(--palette-index-3-75);
--nm-badge-fg: var(--palette-index-3-100);
">
3
</span>Implementation
<link rel="stylesheet" href="namirial-theme.css">
<span style="position:relative; display:inline-block;">
<button class="nm-button nm-button--secondary">
<i class="icon-bell"></i> Alerts
</button>
<span class="nm-badge nm-badge--negative" style="position:absolute; top:-8px; right:-8px;">
12
</span>
</span>CSS classes
| Class | Values | Default |
|---|---|---|
nm-badge--{intent} | primary · secondary · accent · info · positive · negative · warning | none (base tokens) |
nm-badge--dot | strips content/padding to an 8px circle | omit for count/label badges |