Badge

Compact inline marker for status, categories, and notification counts.

Basic

Featured Beta Active Pending Failed
.heex
<div class="flex flex-wrap gap-3 justify-center">
  <.badge color="primary">Featured</.badge>
  <.badge color="info">Beta</.badge>
  <.badge color="success">Active</.badge>
  <.badge color="warning">Pending</.badge>
  <.badge color="danger">Failed</.badge>
</div>

Variants

Solid Soft Surface Outline Dashed Ghost
.heex
<.badge variant="solid" color="info">Solid</.badge>
<.badge variant="soft" color="info">Soft</.badge>
<.badge variant="surface" color="info">Surface</.badge>
<.badge variant="outline" color="info">Outline</.badge>
<.badge variant="dashed" color="info">Dashed</.badge>
<.badge variant="ghost" color="info">Ghost</.badge>

Color and variant matrix

Solid Soft Surface Outline Dashed Ghost
Solid Soft Surface Outline Dashed Ghost
Solid Soft Surface Outline Dashed Ghost
Solid Soft Surface Outline Dashed Ghost
Solid Soft Surface Outline Dashed Ghost
.heex
<.badge variant="solid" color="primary">Solid</.badge>
<.badge variant="soft" color="primary">Soft</.badge>
<.badge variant="surface" color="primary">Surface</.badge>
<.badge variant="outline" color="primary">Outline</.badge>
<.badge variant="dashed" color="primary">Dashed</.badge>
<.badge variant="ghost" color="primary">Ghost</.badge>

Sizes

Extra small Small Medium Large Extra large
.heex
<div class="flex flex-wrap gap-3 justify-center items-center">
  <.badge size="xs" color="success">Extra small</.badge>
  <.badge size="sm" color="success">Small</.badge>
  <.badge size="md" color="success">Medium</.badge>
  <.badge size="lg" color="success">Large</.badge>
  <.badge size="xl" color="success">Extra large</.badge>
</div>

With icon

Add the icon class to <.icon> so the glyph scales with the badge's size token. Without it, the icon falls back to its native dimensions and breaks the row.

Verified Pending Failed Beta New Trending v2.0 launched 30% off Featured Secure Saved Action required
.heex
<.badge color="success">
  <.icon name="hero-check-circle-solid" class="icon" /> Verified
</.badge>
<.badge color="warning">
  <.icon name="hero-clock" class="icon" /> Pending
</.badge>
<.badge color="danger">
  <.icon name="hero-x-circle-solid" class="icon" /> Failed
</.badge>
<.badge color="info">
  <.icon name="hero-information-circle-solid" class="icon" /> Beta
</.badge>
<.badge variant="solid" color="primary">
  <.icon name="hero-sparkles-solid" class="icon" /> New
</.badge>
<.badge variant="solid" color="warning">
  <.icon name="hero-fire-solid" class="icon" /> Trending
</.badge>
<.badge variant="soft" color="primary">
  <.icon name="hero-rocket-launch-solid" class="icon" /> v2.0 launched
</.badge>
<.badge variant="soft" color="warning">
  <.icon name="hero-tag-solid" class="icon" /> 30% off
</.badge>
<.badge variant="outline" color="primary">
  <.icon name="hero-star-solid" class="icon" /> Featured
</.badge>
<.badge variant="outline" color="success">
  <.icon name="hero-shield-check-solid" class="icon" /> Secure
</.badge>
<.badge variant="dashed" color="info">
  <.icon name="hero-bookmark-solid" class="icon" /> Saved
</.badge>
<.badge variant="ghost" color="warning">
  <.icon name="hero-exclamation-triangle-solid" class="icon" /> Action required
</.badge>

Leading, trailing, and icon-only

Place the icon before or after the label, or drop the label for compact markers. Add aria-label on icon-only badges so screen readers still announce the meaning.

Up 12% Changelog 3 Premium Carbon neutral
.heex
<.badge color="primary">
  <.icon name="hero-arrow-trending-up" class="icon" /> Up 12%
</.badge>
<.badge color="info">
  Changelog <.icon name="hero-arrow-right" class="icon" />
</.badge>
<.badge variant="solid" color="success" aria-label="Verified">
  <.icon name="hero-check" class="icon" />
</.badge>
<.badge variant="solid" color="danger" aria-label="3 unread">
  3
</.badge>

Status dot

A <span> with bg-current picks up the badge's foreground color, so the dot stays in sync with the variant.

Online Away Busy Offline
.heex
<div class="flex flex-wrap gap-3 justify-center">
  <.badge color="success" variant="soft">
    <span class="size-1.5 rounded-full bg-current/70"></span> Online
  </.badge>
  <.badge color="warning" variant="soft">
    <span class="size-1.5 rounded-full bg-current/70"></span> Away
  </.badge>
  <.badge color="info" variant="soft">
    <span class="size-1.5 rounded-full bg-current/70"></span> Busy
  </.badge>
  <.badge color="danger" variant="soft">
    <span class="size-1.5 rounded-full bg-current/70"></span> Offline
  </.badge>
</div>

Notification counter

Combine variant="solid" with size="xs" for compact numeric markers next to a label.

Inbox 12
Mentions 3
Drafts 2
Archive 128
.heex
<.badge variant="solid" color="primary" size="xs">12</.badge>
<.badge variant="solid" color="danger" size="xs">3</.badge>
<.badge variant="soft" color="info" size="xs">2</.badge>
<.badge variant="soft" size="xs">128</.badge>

Inside a button

Drop a badge inside a button to annotate the action. Use ghost or soft at xs to stay subtle next to the parent label.

.heex
<div class="flex flex-wrap gap-3 justify-center">
  <.button variant="outline">
    Changelog
    <.badge variant="soft" color="info" size="xs">3 new</.badge>
  </.button>

  <.button variant="solid" color="primary">
    Upgrade
    <.badge variant="solid" class="bg-white/20 text-white border-white/0" size="xs">Pro</.badge>
  </.button>

  <.button variant="ghost">
    Notifications
    <.badge variant="solid" color="danger" size="xs">9+</.badge>
  </.button>
</div>

Removable filter chips

Badges have no built-in interactive state. Wire them up with phx-click and add cursor-pointer to signal affordance.

Status: Active Owner: Sarah Plan: Pro Region: EU
.heex
<.badge
  :for={tag <- @active_filters}
  variant="dashed"
  color="primary"
  phx-click="remove_filter"
  phx-value-tag={tag}
  class="cursor-pointer"
>
  {tag} <.icon name="hero-x-mark" class="icon" />
</.badge>

Table cell status

Invoice Customer Status Amount
INV-1042 Acme Inc. paid $2,400.00
INV-1041 Globex Co. pending $890.00
INV-1040 Initech overdue $1,250.00
INV-1039 Umbrella draft $0.00
.heex
<.table_row :for={invoice <- @invoices}>
  <:cell>{invoice.number}</:cell>
  <:cell>{invoice.customer}</:cell>
  <:cell>
    <.badge color={invoice_color(invoice.status)} size="sm" class="capitalize">
      {invoice.status}
    </.badge>
  </:cell>
  <:cell class="text-right">{invoice.amount}</:cell>
</.table_row>

Status next to a label

Database
Operational
Queue worker
Degraded
Webhook delivery
Failing
CDN
Operational
.heex
<dl class="grid grid-cols-[auto_auto] gap-x-6 gap-y-2 items-center">
  <dt class="text-sm text-foreground-soft">Database</dt>
  <dd>
    <.badge variant="soft" color="success" size="sm">
      <span class="size-1.5 rounded-full bg-current"></span> Operational
    </.badge>
  </dd>
  <dt class="text-sm text-foreground-soft">Queue worker</dt>
  <dd>
    <.badge variant="soft" color="warning" size="sm">
      <span class="size-1.5 rounded-full bg-current"></span> Degraded
    </.badge>
  </dd>
  <dt class="text-sm text-foreground-soft">Webhook delivery</dt>
  <dd>
    <.badge variant="soft" color="danger" size="sm">
      <span class="size-1.5 rounded-full bg-current"></span> Failing
    </.badge>
  </dd>
</dl>

Custom classes

The class attribute merges with the variant, color, and size styles through Fluxon.ClassMerge; utilities you pass through win where they conflict.

Pill SKU-08421 Active Bold edge
.heex
<div class="flex flex-wrap gap-3 justify-center items-center">
  <.badge class="rounded-full px-2" color="primary">Pill</.badge>
  <.badge class="font-mono" color="info">SKU-08421</.badge>
  <.badge class="uppercase tracking-wider" color="success">Active</.badge>
  <.badge class="border-2" variant="outline" color="warning">Bold edge</.badge>
</div>