Badge
A badge wraps something and pins a marker to its top corner: unread messages on an inbox button, an online dot on an avatar. It takes the thing it marks as children.
Basic badge
4AL12
stack({ direction: 'row', gap: 'xl', align: 'center' },
badge({ content: 4 }, button({ variant: 'soft', color: 'neutral' }, 'Inbox')),
badge({ content: 12 }, avatar({ name: 'Ada Lovelace' })),
)Colors
33333
stack({ direction: 'row', gap: 'xl', align: 'center', wrap: true },
badge({ content: 3, color: 'primary' }, button({ variant: 'soft', color: 'neutral' }, 'Primary')),
badge({ content: 3, color: 'neutral' }, button({ variant: 'soft', color: 'neutral' }, 'Neutral')),
badge({ content: 3, color: 'success' }, button({ variant: 'soft', color: 'neutral' }, 'Success')),
badge({ content: 3, color: 'warning' }, button({ variant: 'soft', color: 'neutral' }, 'Warning')),
badge({ content: 3, color: 'danger' }, button({ variant: 'soft', color: 'neutral' }, 'Danger')),
)Maximum
A count above max renders as n+, so a badge never grows wide enough to unbalance the thing it sits on.
999+250
stack({ direction: 'row', gap: 'xl', align: 'center', wrap: true },
badge({ content: 9 }, button({ variant: 'soft', color: 'neutral' }, 'Nine')),
badge({ content: 250 }, button({ variant: 'soft', color: 'neutral' }, 'Capped at 99')),
badge({ content: 250, max: 999 }, button({ variant: 'soft', color: 'neutral' }, 'max: 999')),
)Dot
A dot says "something changed" without saying how much. Give it a label — a bare dot means nothing to a screen reader, so without one it is hidden from the accessibility tree entirely.
ALOnlineNeeds attention
stack({ direction: 'row', gap: 'xl', align: 'center' },
badge({ dot: true, color: 'success', label: 'Online' }, avatar({ name: 'Ada Lovelace' })),
badge({ dot: true, color: 'warning', label: 'Needs attention' },
iconButton({
label: 'Settings',
variant: 'soft',
color: 'neutral',
icon: icon('settings'),
}),
),
)Labelling the count
A bare number is ambiguous out of context. label becomes the badge’s accessible name, so it reads as "4 unread messages" rather than "4".
4 unread messages
badge({ content: 4, label: '4 unread messages' },
button({ variant: 'soft', color: 'neutral' }, 'Inbox'),
)Props
| Prop | Type | Default | Description |
|---|---|---|---|
content | string | number | — | What the badge shows. Ignored when dot is set. |
color | 'primary' | 'neutral' | 'success' | 'warning' | 'danger' | 'danger' | Badge colour. |
dot | boolean | false | A small dot instead of a value. |
max | number | 99 | Counts above this render as n+. |
label | string | — | Accessible name for the badge itself. |