A badge is a small colored dot holding a count. variant and
onSecondaryBackground are the whole API: there is no label, icon, dismiss or
size prop, and the count is the only thing a badge can say.
Anatomy
Section titled “Anatomy”-
Container the dot itself, colored by33variant, and 16px wide before the count widens it. -
Count a number inside the dot, for how many things are waiting. It is required: with no count, the component renders nothing.33
Give every badge a count
Section titled “Give every badge a count”Badge is a Sticker underneath — the same component with a
round corner radius, a 16px minimum width and 10px text. It inherits Sticker’s
one requirement: a sticker with neither children nor an icon logs a warning and
returns null.
So <Badge variant="alert" /> renders nothing at all: server-rendered, an empty
badge produces an empty parent element and a console warning. The unread dot
with no number is a real pattern and this component is not it. Until Badge can
render without children, a dot on its own is markup of yours, not a badge.
When to use
Section titled “When to use”Use a badge to mark that something has arrived and not been opened yet: unread messages, new results in a tab, items waiting in a queue. The badge marks the thing; the thing it marks is what you click.
If the state needs a word — “Active”, “Pending”, “Beta” — use a Sticker, whose text is what carries its meaning. For a message the reader has to act on, use a Banner. For an explanation, use a Tooltip or plain inline text.
Show one badge at a time
Section titled “Show one badge at a time”A badge carries no words and occupies 16px, so the whole of its signal is that it is the one colored thing in an otherwise quiet view. Put four on a screen and the reader has to compare them to find out which one matters, which is work the badge existed to save. Where several things are counted at once, the counts belong in the content — a column, a list, a heading — rather than in four dots.
Variants
Section titled “Variants”variant is basic, active or alert — grey, purple and red, defaulting to
basic. The names describe color and nothing else: none of them is text the
badge displays, and none of them changes what the count means.
Grey counts something; purple says this is the active or selected one; red says
the count is a problem. onSecondaryBackground adjusts the fill for a tinted
surface, such as inside a panel or a card with a grey background.
Accessibility
Section titled “Accessibility”The count reaches a screen reader as a bare number
Section titled “The count reaches a screen reader as a bare number”Color is the badge’s only channel, so “3” has to be understandable from
somewhere else. Two
places will do it: the labeled thing the badge sits next to, or an aria-label
on the badge itself — Badge passes its remaining props through to the rendered
element, so aria-label lands where it needs to.
Nothing announces a change. The count updates silently, and a reader who has already passed it will not hear that it moved.
Content
Section titled “Content”Cap the count before you pass it
Section titled “Cap the count before you pass it”Nothing in the component caps it. The count renders at 10px inside a 16px pill and never wraps, so a four-digit number either widens the dot into a stripe or, where its container caps the width, truncates to an ellipsis — “120…” is a worse answer than no number. Send “99+” rather than 1,204; past two digits the exact figure has stopped being what the reader wanted from a dot.
| Name | Type |
|---|---|
onSecondaryBackground |
When rendered on a secondary background (e.g. inside a panel or card with a grey fill), set this to true so the component adjusts its colours appropriately for certain variants. |
variant |
Semantic colour variant for the badge.
|
Was this page helpful?