Skip to main content

Badge

A short label for a status, category or count, next to what it describes.

In Content first

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Content first: The topic of an article.

  • Use it when: A state people scan for in a list or table, or a small category label.
  • Not when: A message people must read (alert or toast), or an action (a button).

Instead:

  • Alert: A message, not a label.
  • Button: Something to press.

Variants​

What each variant is for in any design system, then what Content first decided and why. Each sample is the live story with that variant set.

neutraltoneUsed in Content first
Start Storybook to see it live

What it is for

A label with no status meaning: a category, a count, a waiting state.

✓Nothing is wrong and nothing needs doing.
✕The state needs attention.

In Content first

Saved: waiting for you; nothing is wrong.

infotoneNot used in Content first
Start Storybook to see it live

What it is for

News: worth knowing, nothing to act on.

✓Something is happening or coming.
✕Something is wrong or nearly wrong.

In Content first

Topics and reading states need no news tone; status is rare.

successtoneUsed in Content first
Start Storybook to see it live

What it is for

Done, healthy or paid.

✓The outcome people wanted.
✕A state that is only waiting.

In Content first

Finished: you read it to the end.

warningtoneUsed in Content first
Start Storybook to see it live

What it is for

Needs attention soon; nothing has failed yet.

✓A risk people can still act on.
✕Something already failed.

In Content first

Out of date: the facts may have changed since it was written.

dangertoneNot used in Content first
Start Storybook to see it live

What it is for

Failed, blocked or lost; act now.

✓A real failure or loss.
✕Anything that is only unusual.

In Content first

Nothing in an article fails; errors are calm sentences, not labels.

How Content first uses it​

A status
Use Badge pill with a word
Not An icon alone
Status is rare, so readers never learn an icon for it. A word is clear the first time.
Shape of a status badge
Use radius.badge (pill)
Not A rectangle
Pills sit softly next to text.

Why it works this way​

Badge looks the way it does because of 2 answers about this product. Each card is one answer, in three steps: the answer, what it decided for Badge, and what would move if it changed.

How many signals carry each meaning?accessibility.count
1The answer
Two: color and word

Status is rare; color and a word are enough.

2So Badge
  • ✓uses neutral: Saved: waiting for you; nothing is wrong.
  • –does not use info: Topics and reading states need no news tone; status is rare.
  • ✓uses success: Finished: you read it to the end.
  • ✓uses warning: Out of date: the facts may have changed since it was written.
  • –does not use danger: Nothing in an article fails; errors are calm sentences, not labels.
It also shapes Alert: destructive
3If it changed
5
Badge decisions would reopen

No other answer follows from it.

How many tones does it use?voice.count
1The answer
One per moment

Warm by default, calmer for errors.

2So Badge
  • –does not use danger: Nothing in an article fails; errors are calm sentences, not labels.
It also shapes Alert: destructive Toast: danger
3If it changed
1
Badge decision would reopen

No other answer follows from it.

Words​

  • Write to one person: "you", not "users".
  • Short sentences with room to breathe.
  • Explain why before asking for anything.
  • Use: Read, Save for later, You, Next issue. Avoid: Click here, Submit, Users, Content.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Not now
  • content.action.destroy: Remove
  • content.action.retry: Try again
  • content.action.empty-action: Browse guides

See Voice and tone for the whole voice.

Accessibility and keyboard​

Test before you ship:

  • The status is a word; color and icon add to it, never replace it. undefined

Use it in code​

npx open-ds add badge

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Badge reads 17 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Badge's tokens to change Badge alone.

Changes with theme

Content first decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Badge
Cornercomponent.badge.radiusradius.badgevar(--badge-radius)radius.999:9999px
Padding, left and rightcomponent.badge.padding-xspace.gap.tightvar(--badge-padding-x)space.8:0.5rem
Text sizecomponent.badge.font-sizetype.caption.font-sizevar(--badge-font-size)font.size.14:0.875rem
Gapcomponent.badge.gapspace.gap.tightvar(--badge-gap)space.8:0.5rem
Padding, top and bottomcomponent.badge.padding-ycomponent-spacing-map.hairlinevar(--badge-padding-y)space.2:0.125rem
Weightcomponent.badge.font-weighttype.label.font-weightvar(--badge-font-weight)font.weight.600:600
Font familycomponent.badge.font-familytype.caption.font-familyvar(--badge-font-family)font.family.inter:Inter, system-ui, sans-serif
Neutral
Fill
Changes with theme
component.badge.neutral.backgroundcolor.surface.sunkenvar(--badge-neutral-background)Lightstone.light.100:#F6F2EADarkstone.dark.100:#2E2A24
Text
Changes with theme
component.badge.neutral.labelcolor.text.secondaryvar(--badge-neutral-label)Lightstone.light.700:#4A4339Darkstone.dark.500:#CFC6B6
Success
Fill
Changes with theme
component.badge.success.backgroundcolor.status.success.subtlevar(--badge-success-background)Lightgreen.light.100:#DBF7DFDarkgreen.dark.100:#02351B
Textcomponent.badge.success.labelcolor.text.success-on-lightvar(--badge-success-label)green.light.800:#023E17
Warning
Fill
Changes with theme
component.badge.warning.backgroundcolor.status.warning.subtlevar(--badge-warning-background)Lightamber.light.100:#FEE8CFDarkamber.dark.100:#402B00
Textcomponent.badge.warning.labelcolor.text.warning-on-lightvar(--badge-warning-label)amber.light.800:#462A02
Danger
Fill
Changes with theme
component.badge.danger.backgroundcolor.status.danger.subtlevar(--badge-danger-background)Lightred.light.100:#FFDBD8Darkred.dark.100:#4D181A
Textcomponent.badge.danger.labelcolor.text.danger-on-lightvar(--badge-danger-label)red.light.800:#6D0008
Info
Fill
Changes with theme
component.badge.info.backgroundcolor.status.info.subtlevar(--badge-info-background)Lightblue.light.100:#D3E4FFDarkblue.dark.100:#172C4F
Textcomponent.badge.info.labelcolor.text.info-on-lightvar(--badge-info-label)blue.light.800:#001A4E