Badge

span.badge

Badge — a small, static label attached to something else: "New", "Beta", "3 unread", a coloured dot beside a name.

Examples

Status, in a word

View “Status, in a word” as
Shipped Beta Pending 3 unread Online
<span class="badge badge-success">Shipped</span>
<span class="badge badge-subtle badge-info">Beta</span>
<span class="badge badge-warning">Pending</span>
<span class="badge badge-danger badge-round">3<span class="sr-only"> unread</span></span>
<span class="badge badge-dot badge-success"><span class="sr-only">Online</span></span>

A badge is not a status announcement. If the text changes at runtime nothing tells a screen reader — a badge is not focusable, so it may never be read at all.

Announcing a change needs a live region that existed before it, and that is the page’s decision, not this component’s.

Tokens 16

Level 2, declared on .badge itself. Set any of them on that selector to restyle this component without touching the skin.

Level 2 tokens declared by badge
TokenDefault
--badge-white-spacenowrap
--badge-bgvar(--color-surface-sunken)
--badge-border-colorvar(--color-border-subtle)
--badge-border-widthvar(--border-width)
--badge-colorvar(--color-on-surface)
--badge-font-familyvar(--font-secondary)
--badge-font-sizevar(--font-size-xs)
--badge-font-weightvar(--font-weight-semibold)
--badge-gapvar(--space-1)
--badge-padding-block0.125rem
--badge-padding-inlinevar(--space-2)
--badge-radiusvar(--radius-sm)
--badge-dot-size0.625rem
--badge-min-size1.25rem
--badge-tintvar(--color-surface-sunken)
--badge-tint-bordervar(--color-border-strong)

Variants and states

Variants

  • .badge-danger
  • .badge-dot
  • .badge-info
  • .badge-neutral
  • .badge-round
  • .badge-subtle
  • .badge-success
  • .badge-warning

State it reads

None.

Before you ship it

What you have to do 1 requirements

  1. Give a wordless badge a name. .badge-dot and a bare number are not messages. A dot needs <span class="sr-only">Online</span> inside it, and "3" needs <span class="sr-only"> unread</span> after it — with the leading space, or it is announced as "3unread". Nothing in CSS can supply this and nothing can detect that it is missing. Let a badge wrap when its words are not yours. The default is white-space: nowrap, which is right for «New» and for a count and wrong for a status phrase coming out of a feed — and a nowrap badge inside an auto grid track holds that track open at the width of its longest string, which is a page scrolling sideways rather than a badge looking untidy. One declaration on the badge, or on a rule that selects it, hands the wrapping back: .cell-delay .badge { --badge-white-space: normal } Write it on the badge, not on the box around it. white-space is an inherited property and this knob is not: like every other token in this file it is declared on .badge, so a value set on an ancestor is shadowed by the component's own and the badge goes on refusing to wrap — silently, because the ancestor's declaration is perfectly valid and simply never read. A rule that selects the badge from the ancestor, as above, is the form that works. Nothing here can detect the case: whether the text is a label or a sentence is something only the consumer knows. Put the badge next to what it describes, inside the same element the screen reader will read as one phrase. A badge floated to the far side of a row is read after everything between it and its subject.

src/css/components/badge.css · npx mostlycss add badge