Badge
A small pill marking a status, a label or a presence, rendered as
<span is="root-badge">.
Usage
<span is="root-badge" data-color="success">Active</span>
data-variant
and data-color work the way they do on Button: the variant is the shape, the color is the
palette. Unlike a Button, a badge with neither is not a bare outline - it is the Default palette in its
default shape, because a badge is a filled mark by definition.
<span is="root-badge">New</span>
Variants
Two shapes. default carries a short label - a word, an icon, occasionally a count - and
dot carries nothing: it is empty by definition, half the badge's own height
at every size, and it marks a state on something else rather than saying anything of its own.
An empty element has no accessible name, so a dot needs aria-label - and
role="img"
rather than the component's default status, because a state that is drawn once is not a
live region.
<span is="root-badge" data-color="success">Active</span>
<span is="root-badge" data-variant="dot" data-color="success" role="img" aria-label="Online"></span>
<span is="root-badge" data-variant="dot" data-color="neutral" role="img" aria-label="Offline"></span>
Palettes
data-color
names a ramp: default, alternate, info, success,
warning,
danger
and neutral. The value painted is that ramp's -400 step, and the label is a
contrast-color() over it - which is what makes the same seven names work in both schemes,
where the -400 steps sit at opposite ends of their ramps.
<span is="root-badge" data-color="default">Default</span>
<span is="root-badge" data-color="alternate">Alternate</span>
<span is="root-badge" data-color="info">Info</span>
<span is="root-badge" data-color="success">Success</span>
<span is="root-badge" data-color="warning">Warning</span>
<span is="root-badge" data-color="danger">Danger</span>
<span is="root-badge" data-color="neutral">Neutral</span>
Every palette takes the dot:
<span is="root-badge" data-variant="dot" data-color="default" role="img" aria-label="Default"></span>
<span is="root-badge" data-variant="dot" data-color="alternate" role="img" aria-label="Alternate"></span>
<span is="root-badge" data-variant="dot" data-color="info" role="img" aria-label="Info"></span>
<span is="root-badge" data-variant="dot" data-color="success" role="img" aria-label="Online"></span>
<span is="root-badge" data-variant="dot" data-color="warning" role="img" aria-label="Away"></span>
<span is="root-badge" data-variant="dot" data-color="danger" role="img" aria-label="Busy"></span>
<span is="root-badge" data-variant="dot" data-color="neutral" role="img" aria-label="Offline"></span>
Sizes
data-size
takes small, medium and large; medium is the default and needs no
value written. Measured heights are 31.25px for large and 25px for both medium and small - the two are the
same height on purpose, and only the type changes between them (16 / 14.2 / 12.6px). Large also takes the
wider inline padding. The dot follows at half the height: 15.63 / 12.5 / 12.5px.
<span is="root-badge" data-color="default" data-size="large">Large</span>
<span is="root-badge" data-color="default">Medium</span>
<span is="root-badge" data-color="default" data-size="small">Small</span>
<span is="root-badge" data-variant="dot" data-color="danger" data-size="large" role="img" aria-label="Busy"></span>
<span is="root-badge" data-variant="dot" data-color="danger" role="img" aria-label="Busy"></span>
<span is="root-badge" data-variant="dot" data-color="danger" data-size="small" role="img" aria-label="Busy"></span>
Modifiers
data-mask="true"
adds a 2px ring in the page ground, so a badge sitting on top of something else reads as separate from it
rather than as part of it. The border box exists at every variant, so switching the mask on does not
change the badge's height.
The attribute is always in the DOM: the component writes data-mask="false" when
the markup does not, so what a badge is reads out of the element rather than out of an attribute that is
not there.
<span is="root-badge" data-color="danger" data-mask="true">Overdue</span>
<span is="root-badge" data-variant="dot" data-color="success" data-mask="true" role="img" aria-label="Online"></span>
Anchor points
data-anchor
pins the badge to a corner of the thing it marks, and the four read clockwise from the top-left:
top-left, top-right, bottom-right, bottom-left. The
fifth case in the design is inline - that is a badge with no data-anchor, in flow beside its
label.
An anchored badge is absolutely positioned, so the host has to be the positioned ancestor: mark it
data-badge-host. It sits in the host's corner rather than outside it, which on a round host
is where the circle's edge runs - and that overlap is what
data-mask="true"
is for: the ring separates the mark from the surface under it.
All four corners, with a dot on each:
<span data-badge-host>
<span is="root-avatar" aria-label="Ada Lovelace">AL</span>
<span is="root-badge" data-variant="dot" data-color="warning" data-anchor="top-left" data-mask="true" role="img" aria-label="Away"></span>
</span>
<span data-badge-host>
<span is="root-avatar" aria-label="Grace Hopper">GH</span>
<span is="root-badge" data-variant="dot" data-color="success" data-anchor="top-right" data-mask="true" role="img" aria-label="Online"></span>
</span>
<span data-badge-host>
<span is="root-avatar" aria-label="Alan Turing">AT</span>
<span is="root-badge" data-variant="dot" data-color="danger" data-anchor="bottom-right" data-mask="true" role="img" aria-label="Busy"></span>
</span>
<span data-badge-host>
<span is="root-avatar" aria-label="Katherine Johnson">KJ</span>
<span is="root-badge" data-variant="dot" data-color="neutral" data-anchor="bottom-left" data-mask="true" role="img" aria-label="Offline"></span>
</span>
Cases
The five the design calls out, in the order it calls them:
A dot for presence - online, offline, "there is something new". It is the
least intrusive form and it is empty: no number, no word, nothing to read. Its meaning comes from where
it sits and from its aria-label.
A count when the quantity really is the information, which is the exception rather than the rule - a badge normally carries a word. Past two digits, cap it: a badge that keeps growing shifts the host's layout.
<span is="root-badge" data-color="danger" data-size="small">99+</span>
A status label - a short word instead of a number, for outcomes rather than counts. Keep it to one word.
<span is="root-badge" data-color="success">Done</span>
With a leading icon, when the color alone would be ambiguous: the icon carries the meaning and the label qualifies it.
<span is="root-badge" data-color="warning"><i is="root-icon" data-icon="clock"></i>Pending</span>
A neutral count for a count with no urgency. Reserve danger for what
actually needs attention - a red badge on every item stops signalling anything.
<span is="root-badge" data-color="neutral" data-size="small">12</span>
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-variant |
'default' | 'dot' |
'default' |
Shape: a labelled pill, or an empty dot half its height |
data-color |
'default' | 'alternate' | 'info' | 'success' | 'warning' | 'danger' | 'neutral'
|
'default' |
Which ramp supplies the surface |
data-size |
'small' | 'medium' | 'large' |
'medium' |
Height, inline padding and type step |
data-mask |
'true' | 'false' |
'false' |
2px ring in the page ground; written by the component when absent |
data-anchor |
'top-left' | 'top-right' | 'bottom-right' | 'bottom-left' |
- | Pins the badge to a corner of a [data-badge-host], clockwise from the top-left |
role |
string |
'status' |
Set by the component when absent |
aria-label |
string |
- | Accessible name; required on a dot, which has no content |
Extends
HTMLSpanElement - use with <span is="root-badge">.