Skip to main content
Pricing

Badge

Free

A small label attached to another element to convey counts, statuses, or short categorical labels. Comes in 5 colour variants (Default, Info, Success, Warning, Error) and 2 sizes (SM, MD). Commonly used on icons, avatars, and navigation items to indicate unread counts, statuses, or priority levels.

16 variants

Variant
DefaultSize SM
DefaultSize MD

Variants

VariantDescriptionWhen to use
DefaultNeutral grey badge for general-purpose labels.Use for non-semantic labels — categories, version numbers, or neutral metadata.
Outline
Dot
Removable

Usage Guidelines

Do

Keep badge text short — one or two words maximum.

Don't

Use badges for long text — use a Tag or inline message instead.

Do

Use colour to reinforce meaning, not as the sole indicator.

Don't

Rely solely on colour to convey meaning — always include text.

Do

Position badges consistently relative to their parent element.

Don't

Stack more than two badges on a single element.

Do

Use numeric badges with aria-label to provide context — e.g., "3 unread messages".

Don't

Use Error badges for non-critical states.

Code

HTML
<span class="lex-badge lex-badge--default">Draft</span>
<span class="lex-badge lex-badge--info">New</span>
<span class="lex-badge lex-badge--success">Active</span>
<span class="lex-badge lex-badge--warning">Pending</span>
<span class="lex-badge lex-badge--error">Failed</span>

<!-- Numeric badge on icon -->
<button class="lex-icon-button" aria-label="Notifications, 3 unread">
  <svg><!-- bell icon --></svg>
  <span class="lex-badge lex-badge--error lex-badge--sm">3</span>
</button>
CSS Custom Properties
.lex-badge {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--lex-badge-px, 8px);
  height: var(--lex-badge-height, 22px);
  font-size: var(--lex-badge-font-size, 12px);
  font-weight: 500;
  border-radius: var(--lex-badge-radius, var(--lex-radius-pill));
  line-height: 1;
}

.lex-badge--default {
  background: var(--lex-badge-bg, var(--lex-bg-surface-subtle));
  color: var(--lex-badge-text, var(--lex-text-secondary));
}

.lex-badge--info {
  background: var(--lex-badge-info-bg);
  color: var(--lex-badge-info-text);
}

.lex-badge--success {
  background: var(--lex-badge-success-bg);
  color: var(--lex-badge-success-text);
}

.lex-badge--warning {
  background: var(--lex-badge-warning-bg);
  color: var(--lex-badge-warning-text);
}

.lex-badge--error {
  background: var(--lex-badge-error-bg);
  color: var(--lex-badge-error-text);
}

.lex-badge--sm {
  height: var(--lex-badge-height-sm, 18px);
  padding: 0 var(--lex-badge-px-sm, 5px);
  font-size: var(--lex-badge-font-size-sm, 11px);
}
React
// Using Lexicon CSS classes with React

export function StatusBadges() {
  return (
    <div style={{ display: 'flex', gap: 8 }}>
      <Badge variant="default">Draft</Badge>
      <Badge variant="info">New</Badge>
      <Badge variant="success">Active</Badge>
      <Badge variant="warning">Pending</Badge>
      <Badge variant="error">Failed</Badge>
    </div>
  );
}

export function NotificationIcon() {
  return (
    <IconButton aria-label="Notifications, 3 unread">
      <BellIcon />
      <Badge variant="error" size="sm">3</Badge>
    </IconButton>
  );
}

Design Tokens

TokenValue (dark)Value (light)CSS property
--lex-badge-bgbg
--lex-badge-texttext
--lex-badge-radiusradius
--lex-badge-paddingpadding
--lex-badge-font-sizesize

Accessibility

  • Badges with counts should use aria-label on the parent to provide context — e.g., "3 unread messages".
  • Do not rely on colour alone — the text label must convey meaning independently.
  • Ensure badge text meets 4.5:1 contrast ratio against the badge background.
  • Decorative badges (no interactive parent) can use aria-hidden="true" if the same information is conveyed elsewhere.

Keyboard Interactions

N/ABadges are not focusable — they inherit keyboard behaviour from their parent element.