Badges

Badges are small status descriptors used to highlight item properties, counts, or states. They provide visual emphasis and quick recognition of important information.


Simple Badges

Basic badges for categorization and labels.

Default Primary Secondary
<span class="Badge">Default</span>
<span class="Badge Badge--primary">Primary</span>
<span class="Badge Badge--secondary">Secondary</span>
<span class="Badge">Default</span>
<span class="Badge Badge--primary">Primary</span>
<span class="Badge Badge--secondary">Secondary</span>

Status Badges

Semantic badges to indicate states like success, warning, or error.

Active Pending Failed New
<span class="Badge Badge--success">Active</span>
<span class="Badge Badge--warning">Pending</span>
<span class="Badge Badge--error">Failed</span>
<span class="Badge Badge--info">New</span>
<span class="Badge Badge--success">Active</span>
<span class="Badge Badge--warning">Pending</span>
<span class="Badge Badge--error">Failed</span>
<span class="Badge Badge--info">New</span>

Badge Sizes

Badges come in three sizes: small, medium (default), and large.

Small Medium Large
<span class="Badge Badge--primary Badge--small">Small</span>
<span class="Badge Badge--primary">Medium</span>
<span class="Badge Badge--primary Badge--large">Large</span>
<span class="Badge Badge--primary Badge--small">Small</span>
<span class="Badge Badge--primary">Medium</span>
<span class="Badge Badge--primary Badge--large">Large</span>

Pill Badges

Fully rounded badges for a softer appearance.

Default Primary Success Warning Error
<span class="Badge Badge--pill">Default</span>
<span class="Badge Badge--pill Badge--primary">Primary</span>
<span class="Badge Badge--pill Badge--success">Success</span>
<span class="Badge Badge--pill Badge--warning">Warning</span>
<span class="Badge Badge--pill Badge--error">Error</span>
<span class="Badge Badge--pill Badge--primary">Primary</span>
<span class="Badge Badge--pill Badge--success">Success</span>

Outline Badges

Badges with transparent background and colored border.

Default Primary Success Warning Error
<span class="Badge Badge--outline">Default</span>
<span class="Badge Badge--outline Badge--primary">Primary</span>
<span class="Badge Badge--outline Badge--success">Success</span>
<span class="Badge Badge--outline Badge--warning">Warning</span>
<span class="Badge Badge--outline Badge--error">Error</span>
<span class="Badge Badge--outline Badge--primary">Primary</span>
<span class="Badge Badge--outline Badge--success">Success</span>

Badges with Icons

Add icons for visual reinforcement.

Complete Pending Error Info
<span class="Badge Badge--success">
<i class="ph ph-check-circle Badge-icon"></i>
Complete
</span>
<span class="Badge Badge--warning">
<i class="ph ph-clock Badge-icon"></i>
Pending
</span>
<span class="Badge Badge--error">
<i class="ph ph-warning Badge-icon"></i>
Error
</span>
<span class="Badge Badge--info">
<i class="ph ph-info Badge-icon"></i>
Info
</span>
<span class="Badge Badge--success">
    <i class="ph ph-check-circle Badge-icon"></i>
    Complete
</span>
New Feature Settings
<span class="Badge Badge--primary">
New Feature
<i class="ph ph-arrow-right Badge-icon Badge-icon--trailing"></i>
</span>
<span class="Badge Badge--secondary">
Settings
<i class="ph ph-gear Badge-icon Badge-icon--trailing"></i>
</span>
<span class="Badge Badge--primary">
    New Feature
    <i class="ph ph-arrow-right Badge-icon Badge-icon--trailing"></i>
</span>

Dot Indicator

Minimal status indicator without text.

<span class="Badge Badge--dot"></span>
<span class="Badge Badge--dot Badge--success"></span>
<span class="Badge Badge--dot Badge--warning"></span>
<span class="Badge Badge--dot Badge--error"></span>
<span class="Badge Badge--dot Badge--primary"></span>
<span class="Badge Badge--dot Badge--success"></span>
<span class="Badge Badge--dot Badge--error"></span>
Online
Away
Offline
<div style="display: flex; align-items: center; gap: var(--space-2);">
<span class="Badge Badge--dot Badge--success"></span>
<span style="font-size: 0.875rem;">Online</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-2);">
<span class="Badge Badge--dot Badge--warning"></span>
<span style="font-size: 0.875rem;">Away</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-2);">
<span class="Badge Badge--dot Badge--error"></span>
<span style="font-size: 0.875rem;">Offline</span>
</div>

Count Badges

Badges for displaying numeric counts.

5 12 99+
<span class="Badge Badge--count">5</span>
<span class="Badge Badge--count Badge--primary">12</span>
<span class="Badge Badge--count Badge--error">99+</span>
<span class="Badge Badge--count">5</span>
<span class="Badge Badge--count Badge--primary">12</span>
<span class="Badge Badge--count Badge--error">99+</span>

Badge Positioning

Common patterns for positioning badges relative to other elements.

<button class="Button Button--icon Button--secondary" style="position: relative;" aria-label="Notifications">
<i class="ph ph-bell"></i>
<span class="Badge Badge--count Badge--error Badge--positioned">3</span>
</button>
<button class="Button Button--icon Button--secondary" style="position: relative;" aria-label="Messages">
<i class="ph ph-envelope"></i>
<span class="Badge Badge--count Badge--primary Badge--positioned">12</span>
</button>
<button class="Button Button--icon Button--secondary" style="position: relative;" aria-label="Cart">
<i class="ph ph-shopping-cart"></i>
<span class="Badge Badge--dot Badge--error Badge--positioned"></span>
</button>
<button class="Button Button--icon" style="position: relative;">
    <i class="ph ph-bell"></i>
    <span class="Badge Badge--count Badge--error Badge--positioned">3</span>
</button>
User
User
User 5
<div style="display: flex; gap: var(--space-6);">
<div style="position: relative; display: inline-block;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=badge1" class="Avatar" alt="User">
<span class="Badge Badge--dot Badge--success Badge--avatar"></span>
</div>
<div style="position: relative; display: inline-block;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=badge2" class="Avatar" alt="User">
<span class="Badge Badge--dot Badge--warning Badge--avatar"></span>
</div>
<div style="position: relative; display: inline-block;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=badge3" class="Avatar" alt="User">
<span class="Badge Badge--count Badge--error Badge--avatar" style="font-size: 0.65rem;">5</span>
</div>
</div>
<div style="position: relative; display: inline-block;">
    <img src="..." class="Avatar" alt="User">
    <span class="Badge Badge--dot Badge--success Badge--avatar"></span>
</div>

Interactive Badges

Badges that can be clicked or dismissed.

Filter Active Tag Name
<span class="Badge Badge--primary Badge--dismissible">
Filter Active
<button class="Badge-dismiss" aria-label="Remove filter">
<i class="ph ph-x"></i>
</button>
</span>
<span class="Badge Badge--secondary Badge--dismissible">
Tag Name
<button class="Badge-dismiss" aria-label="Remove tag">
<i class="ph ph-x"></i>
</button>
</span>
<span class="Badge Badge--primary Badge--dismissible">
    Filter Active
    <button class="Badge-dismiss" aria-label="Remove filter">
        <i class="ph ph-x"></i>
    </button>
</span>
<a href="#" class="Badge Badge--primary Badge--clickable">View Details</a>
<a href="#" class="Badge Badge--outline Badge--clickable">Documentation</a>
<a href="#" class="Badge Badge--primary Badge--clickable">View Details</a>

Common Patterns

Table Row Status

Order #12345 Delivered Today
Order #12346 In Transit Est. Tomorrow
Order #12347 Cancelled
<div style="display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3); background: var(--bg-s); border-radius: var(--r-m);">
<span style="flex: 1; font-weight: 500;">Order #12345</span>
<span class="Badge Badge--success">Delivered</span>
<span style="color: var(--fg-3); font-size: 0.875rem;">Today</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3); background: var(--bg-s); border-radius: var(--r-m); margin-top: var(--space-2);">
<span style="flex: 1; font-weight: 500;">Order #12346</span>
<span class="Badge Badge--warning">In Transit</span>
<span style="color: var(--fg-3); font-size: 0.875rem;">Est. Tomorrow</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-4); padding: var(--space-3); background: var(--bg-s); border-radius: var(--r-m); margin-top: var(--space-2);">
<span style="flex: 1; font-weight: 500;">Order #12347</span>
<span class="Badge Badge--error">Cancelled</span>
<span style="color: var(--fg-3); font-size: 0.875rem;">—</span>
</div>

User List with Status

Sarah
Sarah Chen
Online
Admin
John
John Smith
Away
Editor
Mike
Mike Johnson
Offline
Viewer
<div style="display: flex; flex-direction: column; gap: var(--space-3); max-width: 320px;">
<div style="display: flex; align-items: center; gap: var(--space-3);">
<div style="position: relative;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=user1" class="Avatar Avatar--small" alt="Sarah">
<span class="Badge Badge--dot Badge--success Badge--avatar"></span>
</div>
<div style="flex: 1;">
<div style="font-weight: 500; font-size: 0.9rem;">Sarah Chen</div>
<div style="font-size: 0.75rem; color: var(--fg-3);">Online</div>
</div>
<span class="Badge Badge--primary Badge--small">Admin</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-3);">
<div style="position: relative;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=user2" class="Avatar Avatar--small" alt="John">
<span class="Badge Badge--dot Badge--warning Badge--avatar"></span>
</div>
<div style="flex: 1;">
<div style="font-weight: 500; font-size: 0.9rem;">John Smith</div>
<div style="font-size: 0.75rem; color: var(--fg-3);">Away</div>
</div>
<span class="Badge Badge--secondary Badge--small">Editor</span>
</div>
<div style="display: flex; align-items: center; gap: var(--space-3);">
<div style="position: relative;">
<img src="https://api.dicebear.com/7.x/avataaars/svg?seed=user3" class="Avatar Avatar--small" alt="Mike">
<span class="Badge Badge--dot Badge--avatar" style="background-color: var(--fg-3);"></span>
</div>
<div style="flex: 1;">
<div style="font-weight: 500; font-size: 0.9rem;">Mike Johnson</div>
<div style="font-size: 0.75rem; color: var(--fg-3);">Offline</div>
</div>
<span class="Badge Badge--secondary Badge--small">Viewer</span>
</div>
</div>

Feature Tags

Featured New

Advanced Analytics

Track performance with real-time dashboards and detailed reports.

Charts Exports API
<div class="Card" style="max-width: 360px;">
<div class="Card-body">
<div style="display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-3);">
<span class="Badge Badge--pill Badge--primary Badge--small">Featured</span>
<span class="Badge Badge--pill Badge--info Badge--small">New</span>
</div>
<h4 class="Card-title">Advanced Analytics</h4>
<p class="Card-text">Track performance with real-time dashboards and detailed reports.</p>
<div style="display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-4);">
<span class="Badge Badge--outline Badge--small">Charts</span>
<span class="Badge Badge--outline Badge--small">Exports</span>
<span class="Badge Badge--outline Badge--small">API</span>
</div>
</div>
</div>

Notification Header

Notifications

4 new
<div style="display: flex; align-items: center; justify-content: space-between; padding: var(--space-4); background: var(--bg-s); border-radius: var(--r-m); max-width: 400px;">
<div style="display: flex; align-items: center; gap: var(--space-3);">
<h4 style="margin: 0; font-size: 1rem;">Notifications</h4>
<span class="Badge Badge--error Badge--small">4 new</span>
</div>
<button class="Button Button--ghost Button--small">Mark all read</button>
</div>

Customization

Override badge styles using CSS custom properties:

/* Custom brand badge */
.Badge--brand {
  background-color: oklch(60% 0.15 280 / 0.15);
  color: oklch(50% 0.15 280);
}

/* Larger count badge */
.Badge--count-lg {
  min-width: 28px;
  height: 28px;
  font-size: 0.8rem;
  padding: 0 var(--space-2);
}

/* Animated dot (pulsing) */
.Badge--dot.Badge--pulse {
  animation: badge-pulse 2s infinite;
}

@keyframes badge-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Bordered badge */
.Badge--bordered {
  border: 1.5px solid currentColor;
  background-color: transparent;
}

/* Custom spacing for tight layouts */
.Badge--tight {
  padding: 0 var(--space-1);
  font-size: 0.65rem;
}

API Reference

Base & Variant Classes

ClassDescription
.BadgeBase badge styling
.Badge--primaryPrimary color variant
.Badge--secondarySecondary/neutral color variant
.Badge--successSuccess/positive state
.Badge--warningWarning/caution state
.Badge--errorError/danger state
.Badge--infoInformational state

Size & Shape Classes

ClassDescription
.Badge--smallSmaller badge size
.Badge--largeLarger badge size
.Badge--pillFully rounded pill shape
.Badge--outlineTransparent background with border
.Badge--dotMinimal dot indicator (no text)
.Badge--countCircular count badge

Positioning & Interactive Classes

ClassDescription
.Badge--positionedAbsolute positioning for overlays
.Badge--avatarPositioning for avatar overlays
.Badge--dismissibleBadge with remove button
.Badge--clickableInteractive link/button badge
.Badge-iconLeading icon styling
.Badge-icon--trailingTrailing icon positioning
.Badge-dismissDismiss button inside badge

Attributes

AttributeDescription
aria-labelRequired for dot indicators without visible text
aria-hiddenUse on count badges when count is announced via parent

CSS Reference

/* Base Badge */
.Badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--r-s);
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  background-color: var(--bg-s);
  color: var(--fg);
  border: 1px solid transparent;
}

/* Colors */
.Badge--primary {
  background-color: oklch(60% 0.15 250 / 0.15);
  color: oklch(50% 0.15 250);
}

.Badge--secondary {
  background-color: var(--bg-s);
  color: var(--fg-3);
  border-color: var(--bd);
}

.Badge--success {
  background-color: oklch(65% 0.15 150 / 0.15);
  color: oklch(45% 0.15 150);
}

.Badge--warning {
  background-color: oklch(75% 0.15 80 / 0.15);
  color: oklch(50% 0.15 80);
}

.Badge--error {
  background-color: oklch(55% 0.2 25 / 0.15);
  color: oklch(50% 0.2 25);
}

.Badge--info {
  background-color: oklch(65% 0.15 220 / 0.15);
  color: oklch(50% 0.15 220);
}

/* Sizes */
.Badge--small {
  padding: 0 var(--space-1);
  font-size: 0.65rem;
}

.Badge--large {
  padding: var(--space-2) var(--space-3);
  font-size: 0.875rem;
}

/* Pill */
.Badge--pill {
  border-radius: 9999px;
}

/* Outline */
.Badge--outline {
  background-color: transparent;
}

.Badge--outline.Badge--primary {
  border-color: oklch(60% 0.15 250);
  color: oklch(60% 0.15 250);
}

.Badge--outline.Badge--success {
  border-color: oklch(55% 0.15 150);
  color: oklch(55% 0.15 150);
}

.Badge--outline.Badge--warning {
  border-color: oklch(60% 0.15 80);
  color: oklch(60% 0.15 80);
}

.Badge--outline.Badge--error {
  border-color: oklch(55% 0.2 25);
  color: oklch(55% 0.2 25);
}

/* Dot */
.Badge--dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border-radius: 50%;
  background-color: var(--fg-3);
}

.Badge--dot.Badge--success {
  background-color: oklch(55% 0.15 150);
}

.Badge--dot.Badge--warning {
  background-color: oklch(70% 0.15 80);
}

.Badge--dot.Badge--error {
  background-color: oklch(55% 0.2 25);
}

.Badge--dot.Badge--primary {
  background-color: var(--accent);
}

/* Count */
.Badge--count {
  min-width: 20px;
  height: 20px;
  padding: 0 var(--space-1);
  border-radius: 10px;
  text-align: center;
  justify-content: center;
}

/* Positioning */
.Badge--positioned {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  font-size: 0.65rem;
}

.Badge--avatar {
  position: absolute;
  bottom: 0;
  right: 0;
  border: 2px solid var(--bg);
}

/* Icon */
.Badge-icon {
  font-size: 0.9em;
}

.Badge-icon--trailing {
  order: 1;
}

/* Dismissible */
.Badge--dismissible {
  padding-right: var(--space-1);
}

.Badge-dismiss {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  padding: 0;
  margin-left: var(--space-1);
  background: none;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  color: inherit;
  opacity: 0.7;
  transition: opacity 0.15s;
}

.Badge-dismiss:hover {
  opacity: 1;
  background-color: oklch(0% 0 0 / 0.1);
}

/* Clickable */
.Badge--clickable {
  cursor: pointer;
  text-decoration: none;
  transition: all 0.15s;
}

.Badge--clickable:hover {
  filter: brightness(0.95);
}

Accessibility

Color Independence

<!-- Don't rely on color alone — include text or icons -->
<span class="Badge Badge--success">
    <i class="ph ph-check-circle Badge-icon"></i>
    Complete
</span>

<!-- Not just color -->
<span class="Badge Badge--error">Error</span>

Screen Reader Context

<!-- Provide context for count badges -->
<button class="Button Button--icon" aria-label="Notifications, 3 unread">
    <i class="ph ph-bell"></i>
    <span class="Badge Badge--count" aria-hidden="true">3</span>
</button>

<!-- For status dots, use aria-label -->
<span class="Badge Badge--dot Badge--success" aria-label="Online"></span>

Dismissible Badges

<!-- Always provide accessible dismiss button -->
<span class="Badge Badge--dismissible">
    Filter: Active
    <button class="Badge-dismiss" aria-label="Remove Active filter">
        <i class="ph ph-x"></i>
    </button>
</span>

Best Practices

Do

  • Keep text short — 1-2 words maximum
  • Use semantic colors — Green for success, red for errors
  • Include icons for clarity — Helps users with color blindness
  • Position consistently — Same placement across similar elements
  • Use for quick scanning — Badges should be glanceable

Don’t

  • Overuse badges — Too many reduces impact
  • Rely on color alone — Always pair with text or icons
  • Use for long content — That’s what labels or tags are for
  • Mix too many colors — Stick to 2-3 per view
  • Hide important info — Critical statuses need more than a dot