Badge
FreeA small label attached to another element to convey counts, statuses, or short categorical labels. Comes in 5 colour variants (Default, Info, Success, Warning, Error) and 2 sizes (SM, MD). Commonly used on icons, avatars, and navigation items to indicate unread counts, statuses, or priority levels.
16 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Default | Neutral grey badge for general-purpose labels. | Use for non-semantic labels — categories, version numbers, or neutral metadata. |
| Outline | ||
| Dot | ||
| Removable |
Usage Guidelines
Keep badge text short — one or two words maximum.
Use badges for long text — use a Tag or inline message instead.
Use colour to reinforce meaning, not as the sole indicator.
Rely solely on colour to convey meaning — always include text.
Position badges consistently relative to their parent element.
Stack more than two badges on a single element.
Use numeric badges with aria-label to provide context — e.g., "3 unread messages".
Use Error badges for non-critical states.
Code
<span class="lex-badge lex-badge--default">Draft</span>
<span class="lex-badge lex-badge--info">New</span>
<span class="lex-badge lex-badge--success">Active</span>
<span class="lex-badge lex-badge--warning">Pending</span>
<span class="lex-badge lex-badge--error">Failed</span>
<!-- Numeric badge on icon -->
<button class="lex-icon-button" aria-label="Notifications, 3 unread">
<svg><!-- bell icon --></svg>
<span class="lex-badge lex-badge--error lex-badge--sm">3</span>
</button>.lex-badge {
display: inline-flex;
align-items: center;
padding: 0 var(--lex-badge-px, 8px);
height: var(--lex-badge-height, 22px);
font-size: var(--lex-badge-font-size, 12px);
font-weight: 500;
border-radius: var(--lex-badge-radius, var(--lex-radius-pill));
line-height: 1;
}
.lex-badge--default {
background: var(--lex-badge-bg, var(--lex-bg-surface-subtle));
color: var(--lex-badge-text, var(--lex-text-secondary));
}
.lex-badge--info {
background: var(--lex-badge-info-bg);
color: var(--lex-badge-info-text);
}
.lex-badge--success {
background: var(--lex-badge-success-bg);
color: var(--lex-badge-success-text);
}
.lex-badge--warning {
background: var(--lex-badge-warning-bg);
color: var(--lex-badge-warning-text);
}
.lex-badge--error {
background: var(--lex-badge-error-bg);
color: var(--lex-badge-error-text);
}
.lex-badge--sm {
height: var(--lex-badge-height-sm, 18px);
padding: 0 var(--lex-badge-px-sm, 5px);
font-size: var(--lex-badge-font-size-sm, 11px);
}// Using Lexicon CSS classes with React
export function StatusBadges() {
return (
<div style={{ display: 'flex', gap: 8 }}>
<Badge variant="default">Draft</Badge>
<Badge variant="info">New</Badge>
<Badge variant="success">Active</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="error">Failed</Badge>
</div>
);
}
export function NotificationIcon() {
return (
<IconButton aria-label="Notifications, 3 unread">
<BellIcon />
<Badge variant="error" size="sm">3</Badge>
</IconButton>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-badge-bg | — | — | bg |
| --lex-badge-text | — | — | text |
| --lex-badge-radius | — | — | radius |
| --lex-badge-padding | — | — | padding |
| --lex-badge-font-size | — | — | size |
Accessibility
- Badges with counts should use aria-label on the parent to provide context — e.g., "3 unread messages".
- Do not rely on colour alone — the text label must convey meaning independently.
- Ensure badge text meets 4.5:1 contrast ratio against the badge background.
- Decorative badges (no interactive parent) can use aria-hidden="true" if the same information is conveyed elsewhere.