Badge
A badge shows a status or a count at a glance: a short label, a number, or a dot. It is content, not a control.
<tk-badge tone="success">Active</tk-badge> <tk-badge tone="error" treatment="solid" count="120" label="120 unread notifications"></tk-badge> <tk-badge dot tone="success" label="Online"></tk-badge>
Anatomy
A badge is one of three kinds. If you set more than one, dot wins over count, and
count wins over the label.
| Kind | Height | What it is |
|---|---|---|
| label (default slot) | 20px | a pill with one or two words of status |
count |
16px | a pill with a number; above max it shows "99+" |
dot |
8px | a colored dot with no text |
Tones and treatments
<tk-badge>Draft</tk-badge> <tk-badge tone="info">In review</tk-badge> <tk-badge tone="success">Stable</tk-badge> <tk-badge tone="warning">Expiring</tk-badge> <tk-badge tone="error">Failed</tk-badge>
tone sets the meaning: neutral (default), info, success, warning, or error.
treatment="solid" fills the badge instead of tinting it. Keep subtle (default) for most
badges and use solid for notification counts and status that must stand out. treatment
doesn't apply to a dot.
<tk-badge treatment="solid">Draft</tk-badge> <tk-badge treatment="solid" tone="success">Stable</tk-badge> <tk-badge treatment="solid" tone="error" count="3" label="3 failed checks"></tk-badge>
Counts
<tk-badge count="3" label="3 updates"></tk-badge> <tk-badge count="42" label="42 updates"></tk-badge> <tk-badge count="120" label="120 updates"></tk-badge>
max(default 99) caps the number: 120 shows as "99+".count="0"still shows. Hide the badge yourself when there's nothing to count.- Next to a named target, such as a Notifications button, the number is enough. Alone, give
it a
label.
Dots
<tk-badge dot tone="success" label="Online"></tk-badge> <tk-badge dot tone="warning" label="Away"></tk-badge> <tk-badge dot></tk-badge>
A dot is silent to screen readers by default. If it means something, such as online or has
updates, set label or place it next to text that says the same thing. Color alone isn't
enough.
On an avatar
Put a badge in an badge slot. The avatar places it: a count at the
top corner, a dot or label at the bottom. Use one badge per avatar. A dot fits avatars from
24 to 48px; a count reads best on 40px and larger.
<tk-avatar shape="circle" name="Mira Petrova"><tk-badge slot="badge" dot tone="success" label="Online"></tk-badge></tk-avatar> <tk-avatar size="40" shape="circle" name="Ada Lovelace"><tk-badge slot="badge" count="5" tone="error" treatment="solid" label="5 unread messages"></tk-badge></tk-avatar>
When to use
- Use a badge for a standing status or a count: "Active" next to a project, 3 unread messages on a navigation row, a presence dot on an avatar.
- Use a
Tag for anything clickable or removable. A badge never responds to the pointer. - Don't use a badge for a form error. Use the field's error message; see
Field .
Content
- Use one or two words: "Active", "In review". No sentences.
- Use sentence case, with no end punctuation.
- Let
maxformat big numbers. Don't write "99+" yourself. - Write
labelas the full meaning: "120 unread notifications", not "99+".
Do / Don't
| ✅ Do | ❌ Don't |
|---|---|
| Keep the text to one or two words | Write a sentence in a badge |
| Label a meaningful dot, or put text beside it | Let a colored dot carry meaning alone |
Use subtle by default and solid for counts |
Scatter solid badges through a quiet screen |
Let max format large counts |
Write "99+" yourself |
| Use a |
Make a badge clickable |
Related
Avatar : places a badge on its corner.Tag : the interactive, removable chip.
API
Attributes
| Attribute | Type | Default | What it does |
|---|---|---|---|
tone |
neutral | info | success | warning | error |
neutral |
the meaning |
treatment |
subtle | solid |
subtle |
tinted or filled |
dot |
boolean | false |
an 8px dot with no text; wins over count |
count |
number | unset | a number pill, capped at max |
max |
number | 99 |
larger counts show as "max+" |
label |
string | unset | text for screen readers; replaces the visible text, and makes a dot heard |
Slots
| Slot | Content |
|---|---|
| default | the status text; ignored for dot and count |
Events
None. A badge is not interactive.
Tokens
| Tone | subtle |
solid |
Dot |
|---|---|---|---|
neutral |
surface/sunken + text/secondary |
surface/inverse + text/inverse |
icon/secondary |
info |
surface/info + text/info |
fill/info + text/info/on-fill |
icon/info |
success |
surface/success + text/success |
fill/success + text/success/on-fill |
icon/success |
warning |
surface/warning + text/warning |
fill/warning + text/warning/on-fill |
icon/warning |
error |
surface/error + text/error |
fill/error + text/error/on-fill |
icon/error |
Every kind uses radius-full. Padding is space-4 on a count and space-8 on a label; the
text is font-size-xs. Values per theme:
Accessibility
Built in:
- A label badge reads as its text; a count reads as its number.
labelreplaces the visible text for screen readers, so "99+" can be heard as "120 unread notifications".- A dot is hidden from screen readers unless it has a
label. - Not focusable, no keyboard behavior, and no live region.
Your part:
- Give a meaningful dot a
label, or put text next to it. - Give a lone count a
label. - To announce a changing count, put your own live region around the context. The badge doesn't announce updates.
Contrast limits
- Subtle text: at least 4.5:1 in every theme.
- Solid text: at least 3:1. In dark,
successis 3.29:1 anderror3.55:1, under the 4.5:1 text minimum. - Dots: at least 3:1.