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.
<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.
<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.
<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.
<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.
<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.
<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>
<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>
<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.
<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>
<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.
<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
<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
<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
Advanced Analytics
Track performance with real-time dashboards and detailed reports.
<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
| Class | Description |
|---|---|
.Badge | Base badge styling |
.Badge--primary | Primary color variant |
.Badge--secondary | Secondary/neutral color variant |
.Badge--success | Success/positive state |
.Badge--warning | Warning/caution state |
.Badge--error | Error/danger state |
.Badge--info | Informational state |
Size & Shape Classes
| Class | Description |
|---|---|
.Badge--small | Smaller badge size |
.Badge--large | Larger badge size |
.Badge--pill | Fully rounded pill shape |
.Badge--outline | Transparent background with border |
.Badge--dot | Minimal dot indicator (no text) |
.Badge--count | Circular count badge |
Positioning & Interactive Classes
| Class | Description |
|---|---|
.Badge--positioned | Absolute positioning for overlays |
.Badge--avatar | Positioning for avatar overlays |
.Badge--dismissible | Badge with remove button |
.Badge--clickable | Interactive link/button badge |
.Badge-icon | Leading icon styling |
.Badge-icon--trailing | Trailing icon positioning |
.Badge-dismiss | Dismiss button inside badge |
Attributes
| Attribute | Description |
|---|---|
aria-label | Required for dot indicators without visible text |
aria-hidden | Use 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