Badges
How the Badges works with a keyboard and assistive tech, and where it stands against WCAG 2.2 AA.
A Badge is a <span> of text: not a control, not focusable, and read as part of the sentence around it. Its colour supports the label but never replaces it, so "Failed" means failed with or without the red.
Keyboard#
Passes over the badge: it is text, not a control. If it needs to do something, use a Tag or a Button.
Semantics#
<span>Plain text, read in place.
Alwaysaria-hiddenGlyphs and dots are decorative; the label carries the meaning.
Dot, seal and iconsaria-labelA badge with no text needs a name, but aria-label on a <span> is not reliably read. Prefer visually hidden text inside it.
Icon only, Emptyvisually hidden text"3" alone means nothing. Add the noun for screen readers: "3 unread".
Number onlyColour contrast#
Every variant and state has to meet WCAG 2.2 Level AA. Measure the colours as they land on screen: a translucent hover or press wash over whatever sits behind it.
Label · Every intent and appearance
Satoshi Medium 14 is normal text, so 4.5:1 against the badge's fill. Translucent Tint washes are measured over white. Outline appearances sit on white, so they measure at or above Lighter.
WCAG 1.4.3 Contrast (Minimum) ↗Icon only · Icon only
A seal or icon that is the whole badge needs 3:1 against its fill.
WCAG 1.4.11 Non-text Contrast ↗Disabled · Disabled intent
The inactive-component exemption covers controls, and a badge is not one. A Disabled badge that says something still has to be readable; #cbcbcb on #f2f2f2 is not.
WCAG 1.4.3 Contrast (Minimum) ↗Meaning by colour · Every intent
Red, amber and green are not enough on their own. The label says the status.
WCAG 1.4.1 Use of Color ↗Measured contrast#
Label against the badge's background for each intent in Fill, Tint and Lighter, measured on white from the badge tokens. Outline appearances use the same text colour on white. 14 of 21 pairs fall below their minimum (4.5:1 for text, 3:1 for graphics) and are marked in amber.
Motion#
- Badges do not animate.
Checklist#
Write the status as a word. A coloured dot or an empty badge is not a status.
Add the noun to count badges in visually hidden text: "3 unread", "12 open issues".
Fill on Neutral, Success, Warning and Error is white on a mid tone and falls below 4.5:1 (Success at 1.9:1). Every coloured intent's Tint is near 3:1, and Success, Warning and Error stay under 4.5:1 in Lighter too. Only Black, Neutral's Tint and Lighter, and Brand's Fill and Lighter pass; use those until the tokens are darkened.
Disabled reads at about 1.5:1. Use it only where the text does not need to be read, or drop the badge.
A badge whose content changes while the page is open (a live count) is not announced. Pair it with a polite live region if the change matters.
