Skip to main content

Badge

stable

A visual indicator that represents numeric values such as counters.

Overview

Badge is a small indicator that draws attention to a related element, most often by displaying a count. It's used to surface activity or volume — unread notifications, pending tasks, items in a queue — without requiring the user to leave the surface they're on. Badge is decorative; the meaning comes from what it's attached to.

Usage

When to use

  • Showing unread or new counts on a navigation icon (notifications, messages)
  • Indicating items pending review or action on a queue or list item
  • Surfacing activity volume on a tab, list row, or avatar

When not to use

  • Communicating status (active, error, warning) — use Status indicator instead
  • Displaying non-numeric labels or categories — use Tag or Pill instead
  • Conveying critical information that must be read — Badge is supplementary, not primary

Place the badge at the top-right of the thing it marks, overlapping the edge. The badge does not position itself.

Alternatives

Status indicator

Use when communicating state (online, error, warning) rather than quantity.

Tag

Use for non-numeric labels, categories, or filters.

Pill

Use for selectable filters or removable labels.

Anatomy

The badge component is made up of two elements.

  1. Container

    Background shape that wraps the badge content. Has a minimum width that prevents contraction below a circle.

  2. Count

    Numeric value shown inside the badge. Optional — when omitted, the badge renders as a dot.

Variants

Count

The default variant. Displays a numeric value inside the container. The badge expands and contracts to fit the count text, with a minimum width that keeps it from contracting narrower than a circle.

Use when the explicit tally matters — when "how many" is the information the user needs.

Dot

Renders as a circle with no displayed value. Used when the presence of activity is what matters, not the precise count.

Best in condensed layouts where space is tight, or on surfaces where the explicit number would be visually noisy without adding meaning (e.g., on an avatar to indicate "this contact has unread messages").

Max count

A max count limits the number displayed. When the count exceeds the max, a + is appended. The max defaults to 99. Adjust or remove it based on how much horizontal space is available and how precise the tally needs to be. Use it when a count can grow long enough to collide with surrounding content. Counts are numeric and at least 0. Omit the count to render a dot.

States

Badge is non-interactive and has no hover, focus, or pressed states. Document the contextual states that affect appearance.

Default

On dark surface

On a dark surface, use the same count and dot.

At max count

Renders as {maxCount}+ when the underlying count exceeds the max.

Configuration

Theming

Tune via style hook

HookDescriptionDefault
1 Container background (1)
HookDescriptionDefault
--jh-badge-color-background-enabledThe badge background color.--jh-color-content-negative-enabled
1 Container radius (1)
HookDescriptionDefault
--jh-badge-border-radiusThe badge border radius.--jh-border-radius-pill
2 Text color (1)
HookDescriptionDefault
--jh-badge-color-text-enabledThe badge text color.--jh-color-content-on-negative-enabled

Examples

Badge on a notification icon

The canonical use — overlaying an unread count on a navigation icon.

Dot variant on an avatar

Use the dot when the count itself isn't informative — here, presence of unread activity is enough.

Badge with max count

When counts can grow large, cap the displayed value to keep the badge from overflowing into adjacent content.

Badge on a tab

Surfacing pending counts on tab labels lets users see where work waits without changing context.

Count, dot, and max

Omit count for a dot. Set max-count when the tally should stop growing.

Accessibility

WCAG conformance

Badge meets WCAG 2.2 success criteria 1.4.3 (Contrast Minimum) and 1.4.11 (Non-text Contrast) when used with default tokens on the default surface. Custom token overrides are the consumer's responsibility to validate. Also of concern: 1.4.1 (Use of Color) — color is not the only way the count is conveyed — and 1.4.4 (Resize Text) — the badge can scale to 200 percent without losing the count.

Keyboard

Badge is non-interactive and not focusable. It has no keyboard behavior of its own. When Badge wraps an interactive element (like an IconButton), the wrapped element handles keyboard interaction.

Screen reader

By default, Badge's count is read aloud as a number adjacent to its parent element. This is rarely sufficient on its own — "3" by itself doesn't tell a screen reader user what the 3 means.

When Badge is attached to an interactive element, the parent must include the count's meaning in its accessible name. For the dot variant, the parent must say that there is activity, because there is no count to read. When the badge marks a change on the page, such as a new message, put that update in a live region.