Badge
Compact label for status, category, or counters. Composes variant with semantic tone.
Overview
Badge displays compact status indicators, labels, and counts. It appears in tables, forms, headers, cards, and navigation to communicate state at a glance — Active, Pending, Expired, New, Beta, Pro, and notification counts. Badge supports multiple tones (neutral, primary, success, warning, danger, info), variants (solid, outline, soft), and optional dot indicators for live status. It is used across Byteion dashboards, admin panels, ecommerce back offices, ERP/POS workflows, and starter kits.
Why this exists
Without a shared Badge pattern, teams create inconsistent labels — some use bg-green-100 text-green-800, others use inline spans with arbitrary colors, and the color-to-meaning mapping varies per page. Badge unifies status indicators into a consistent, semantic system where color always maps to meaning, sizes are proportional, and accessibility (contrast, screen reader labels) is baked in.
Mental model
- Color communicates meaning — green = active/success, red = error/danger, amber = warning/pending, blue = info, neutral = default/offline. This mapping is consistent across all Byteion components.
- Tone vs Variant — tone is the semantic color (success, danger). Variant is the visual style (solid, outline, soft). A "success" badge can be solid (filled), outline (bordered), or soft (tinted background).
- Dot indicator — a small colored circle preceding the label for live/online status. The dot pulses for actively changing states (online, streaming, recording).
- Badge is not a button — badges are inert labels. If users need to interact (dismiss, edit), use a Button, Tag, or Chip pattern instead.
Badge vs Alert vs Avatar
- Badge — compact inline label for status, version, or count. Use in tables, cards, headers, and navigation items.
- Alert — full-width contextual banner for system messages. Use for form validation, success confirmation, and blocking errors.
- Avatar — circular user image or initials. The optional status dot on Avatar indicates online/offline state.
When to use
- Status in data tables — Active, Pending, Expired, Completed, Cancelled on each row
- Notification counts — unread count on sidebar items, navbar icons, and navigation links
- Version tags — New, Beta, Pro, Enterprise labels on feature cards and pricing tables
- Category tags — product categories, document types, content labels on cards
- Live status indicators — Online, Away, Busy with a pulsing dot next to the label
- Ecommerce order status — Processing, Shipped, Delivered, Returned in order lists
- ERP / POS state labels — In Stock, Low Stock, Out of Stock, Backordered in inventory tables
When not to use
- Do not use badges for actions — use a Button or Dropdown for interactive elements
- Avoid for long text — badges should be 1–3 words. Use Text or Paragraph for longer labels
- Do not use color arbitrarily — map each color to a consistent meaning across the application
- Do not use badges as the only identifier — always pair with a visible label. Icon-only badges need
aria-label - Do not use badges for inline code or keyboard shortcuts — use Text variants
codeandkbdinstead
Basic example
All badge tones displayed across the three variants:
<!-- Solid -->
<span class="inline-flex items-center rounded-full bg-success px-2.5 py-0.5 text-xs font-medium text-success-foreground">Active</span>
<!-- Outline -->
<span class="inline-flex items-center rounded-full border border-success px-2.5 py-0.5 text-xs font-medium text-success">Active</span>
<!-- Soft -->
<span class="inline-flex items-center rounded-full bg-success/10 px-2.5 py-0.5 text-xs font-medium text-success">Active</span>
Variants
| Variant | Classes | Best for |
|---|---|---|
| solid | bg-{tone} text-{tone}-foreground | High emphasis, primary action labels, notification counts |
| outline | border border-{tone} text-{tone} | Low emphasis, nested surfaces, compact tables |
| soft | bg-{tone}/10 text-{tone} | Medium emphasis, status indicators in cards |
Dot indicator
Pair a badge with a colored dot for live status — online, away, busy, offline. The dot is a small inline-block h-1.5 w-1.5 rounded-full bg-current element:
Anatomy
- Container —
inline-flex items-center rounded-fullwith configurable padding and font size - Label — 1–3 word text describing the status, version, or category
- Dot indicator — optional small circle (
h-1.5 w-1.5 rounded-full) for live status - Count — numeric value for notification badges, typically larger or highlighted
Usage guidelines
- Use consistent color-to-meaning mapping across the entire application
- Keep labels to 1–3 words — badges are scannable indicators, not descriptions
- Use solid variant for high-emphasis badges (notification counts, primary status)
- Use outline or soft for low-to-medium emphasis (table status, card labels)
- Use pill shape (
rounded-full) for status badges, rounded rectangle (rounded-md) for category tags - Always pair a colored dot with a text label — color alone is not accessible
Do and Don't
Do
- Map color consistently to meaning across the app
- Keep labels to 1–3 words
- Pair a dot with text for live status
- Use solid for high emphasis, outline for low emphasis
- Add
aria-labelfor icon-only badges
Don't
- Use arbitrary colors — map to semantic meaning
- Use long text in badges
- Use badges for actions — use Button instead
- Use badges as the sole identifier
- Use color alone to convey state
Accessibility
- Color alone is insufficient — always pair a colored dot or background with a text label. Color-blind users cannot distinguish red vs green badges
- Icon-only badges — if a badge has no visible label (e.g., a notification dot on an icon), use
aria-labelto provide screen reader context - Notification counts — screen readers should announce both the count and the item name: "3 unread notifications" rather than just "3"
- Contrast — solid badges use
text-{tone}-foregroundwhich is designed to pass WCAG AA against the filled background
Customization
Badge colors follow Byteion semantic tokens. Each tone (success, danger, warning, info, neutral, primary) has a corresponding background and foreground token. Customize shape (rounded-full vs rounded-md), size (padding and font-size), and variant via standard Tailwind utility classes. The dot animation (pulse, static) can be controlled via animate-pulse or custom keyframes.
HTML example
<!-- Solid badge -->
<span class="inline-flex items-center rounded-full bg-success px-2.5 py-0.5 text-xs font-medium text-success-foreground">Active</span>
<!-- Outline badge -->
<span class="inline-flex items-center rounded-full border border-danger px-2.5 py-0.5 text-xs font-medium text-danger">Expired</span>
<!-- Soft badge with dot -->
<span class="inline-flex items-center gap-1.5 rounded-full bg-success/10 px-2.5 py-0.5 text-xs font-medium text-success">
<span class="inline-block h-1.5 w-1.5 rounded-full bg-current"></span>
Online
</span>
<!-- Notification count -->
<span class="inline-flex items-center justify-center rounded-full bg-primary px-1.5 py-0.5 text-[10px] font-bold text-primary-foreground" aria-label="3 unread notifications">3</span>
React example
React exports <Badge> from @byteion/react. Use tone for semantic color and variant for visual style:
import { Badge } from '@byteion/react';
export default function BadgeDemo() {
return (
<div className="flex flex-wrap items-center gap-3">
<Badge tone="neutral">Default</Badge>
<Badge tone="success">Active</Badge>
<Badge tone="warning">Pending</Badge>
<Badge tone="danger">Error</Badge>
<Badge tone="info">Info</Badge>
<Badge variant="outline" tone="primary">Outline</Badge>
<Badge variant="soft" tone="success">Soft</Badge>
<Badge tone="success">
<span className="mr-1 inline-block h-1.5 w-1.5 rounded-full bg-current" />Live
</Badge>
</div>
);
}
Vue example
Vue exports <Badge> from @byteion/vue with the same tone and variant props:
<script setup lang="ts">
import { Badge } from '@byteion/vue';
</script>
<template>
<div class="flex flex-wrap items-center gap-3">
<Badge tone="neutral">Default</Badge>
<Badge tone="success">Active</Badge>
<Badge tone="warning">Pending</Badge>
<Badge tone="danger">Error</Badge>
<Badge tone="info">Info</Badge>
<Badge variant="outline" tone="primary">Outline</Badge>
<Badge variant="soft" tone="success">Soft</Badge>
<Badge tone="success">
<span class="mr-1 inline-block h-1.5 w-1.5 rounded-full bg-current" />Live
</Badge>
</div>
</template>
API Reference
The Badge component is available in @byteion/react and @byteion/vue:
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | string | neutral | Semantic color: neutral, primary, success, warning, danger, info |
| variant | string | solid | Visual style: solid, outline, soft |
Developer tips
- Define a color-to-status map at the app level — use a constants file or enum (e.g.
STATUS_COLORS: { active: 'success', pending: 'warning', expired: 'danger' }) so status colors are consistent - Use
aria-labelfor count badges — a badge showing "3" should announce "3 unread notifications" to screen readers - Keep count badges small for readability — use
text-[10px]for count badges so the number fits in the pill without overflow - Test color contrast for all tones — solid badges use inverse text (
text-success-foreground) to pass contrast; verify against custom brand colors - Use soft variant for nested surfaces — if a badge appears inside a card that already has a background, the soft variant (
bg-success/10) avoids competing with the card surface
Common mistakes
- Using arbitrary colors — green for active here, blue for active there creates confusion. Map every color to a single semantic meaning
- Omitting text labels — color-only badges are inaccessible. Always pair a dot or background color with a visible text label
- Using badges for actions — badges are inert labels. Users expect clicks to work on buttons, not badges
- Long text in badges — badges have compact padding and small font sizes. Long words overflow or look cramped
- Inconsistent shape — some badges are pills, some are rounded rectangles. Pick one shape per badge type (status vs category) and stay consistent
- Not updating count badges dynamically — static count badges that never update erode trust. Ensure notification counts reflect the actual unread state
Production usage tips
- Test all tone + variant combinations — verify visual contrast and legibility for each combination in light mode, dark mode, and branded themes
- Test count badge overflow — verify that "99+" or "1,234" fits within the badge pill without truncation or overflow
- Test in tables, cards, navbars, sidebars, and modal headers — badge appears in many surfaces; verify padding and alignment are correct
- Test screen reader announcements — verify that count badges announce context ("3 unread") rather than just the number
- Test dynamic updates — verify that badge tone and label update correctly when the underlying status changes
- Keep React and Vue APIs aligned with the core schema —
toneandvariantprops map to HTML class combinations
Premium examples
Pro patterns available in Byteion Pro:
- Animated badge with count increment — a notification badge that animates the count change with a subtle scale or bounce transition
- Pulsing dot for live/online status — an animated pulse on the status dot using
animate-pulsefor real-time indicators - Badge group with overflow count — a row of category badges with a "+N" overflow badge when the count exceeds the container width
- Ecommerce order status badge — a colored badge with an icon prefix for each order status (Processing, Shipped, Delivered, Returned)
- ERP inventory stock badge — stock level badges with color thresholds: green for In Stock, amber for Low Stock, red for Out of Stock
- Feature tag badges with tooltip — badges that display a tooltip on hover with more detail about the tag or version
Related components
- Alert — full-width contextual banner for system status messages
- Avatar — user image or initials with optional status dot
- Tags Input — interactive tag input with removable tags
- Button — interactive action elements, distinct from inert badges
- Empty State — placeholder for empty data with guidance
API Reference
Related components
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
No HTML runtime events are declared by this adapter.
React callbacks
No React callback events are declared by this adapter.
Vue emits
No Vue emitted events are declared by this adapter.
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced component patterns.
Explore Pro Components