Skip to content

Badge <l-badge>

Badges are used to draw attention and display statuses or counts. Commonly used in tabular data, lists, and navigation to indicate state or category.

html
<l-badge variant="success">Active</l-badge>
HTML tag<l-badge>
Native
Progressive
Plain
Shadow-DOM
Plain Custom Element

Badge or tag?

A badge is a value the user reads. When the chip is something the user operates — a filter to toggle, a token to remove — use <l-tag>.

Options

Appearance

Add appearance="filled" (tinted background, no border), appearance="filled-outlined" (tinted background with border), or appearance="accent" (strong background, contrast text). Default is outlined (border, no background).

Outlined Default Info Success Warning Danger
Filled Default Info Success Warning Danger
Filled outlined Default Info Success Warning Danger
Accent Default Info Success Warning Danger
Code
html
<div class="flex flex-col gap-3">
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Outlined</span>
    <l-badge>Default</l-badge>
    <l-badge variant="info">Info</l-badge>
    <l-badge variant="success">Success</l-badge>
    <l-badge variant="warning">Warning</l-badge>
    <l-badge variant="danger">Danger</l-badge>
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Filled</span>
    <l-badge appearance="filled">Default</l-badge>
    <l-badge
      appearance="filled"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      appearance="filled"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      appearance="filled"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      appearance="filled"
      variant="danger"
      >Danger</l-badge
    >
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Filled outlined</span>
    <l-badge appearance="filled-outlined">Default</l-badge>
    <l-badge
      appearance="filled-outlined"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      appearance="filled-outlined"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      appearance="filled-outlined"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      appearance="filled-outlined"
      variant="danger"
      >Danger</l-badge
    >
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Accent</span>
    <l-badge appearance="accent">Default</l-badge>
    <l-badge
      appearance="accent"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      appearance="accent"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      appearance="accent"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      appearance="accent"
      variant="danger"
      >Danger</l-badge
    >
  </div>
</div>

Icon

Put an <l-icon> at either end of the badge, or both. It resolves to 1em and inherits the label's color, and the badge tightens the padding on that edge to keep the chip balanced. A raw <iconify-icon> or an inline <svg> works the same way.

For a trailing icon, wrap the label in a <span>: CSS counts elements, not text, so that is what tells the badge which end the icon is on.

Leave the icon decorative — the badge's text carries the meaning.

Lyon branch Restricted Signed
Code
html
<div class="flex flex-wrap items-center gap-2">
  <l-badge>
    <l-icon name="mdi:map-marker-outline"></l-icon>
    Lyon branch
  </l-badge>
  <l-badge variant="warning">
    <span>Restricted</span>
    <l-icon name="mdi:lock-outline"></l-icon>
  </l-badge>
  <l-badge
    variant="success"
    appearance="filled"
    pill
  >
    <l-icon name="mdi:check-circle-outline"></l-icon>
    <span>Signed</span>
    <l-icon name="mdi:open-in-new"></l-icon>
  </l-badge>
</div>

Pill

Add the pill attribute for a fully rounded shape.

Outlined Default Info Success Warning Danger
Filled Default Info Success Warning Danger
Filled outlined Default Info Success Warning Danger
Accent Default Info Success Warning Danger
Code
html
<div class="flex flex-col gap-3">
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Outlined</span>
    <l-badge pill>Default</l-badge>
    <l-badge
      pill
      variant="info"
      >Info</l-badge
    >
    <l-badge
      pill
      variant="success"
      >Success</l-badge
    >
    <l-badge
      pill
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      pill
      variant="danger"
      >Danger</l-badge
    >
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Filled</span>
    <l-badge
      pill
      appearance="filled"
      >Default</l-badge
    >
    <l-badge
      pill
      appearance="filled"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      pill
      appearance="filled"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      pill
      appearance="filled"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      pill
      appearance="filled"
      variant="danger"
      >Danger</l-badge
    >
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Filled outlined</span>
    <l-badge
      pill
      appearance="filled-outlined"
      >Default</l-badge
    >
    <l-badge
      pill
      appearance="filled-outlined"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      pill
      appearance="filled-outlined"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      pill
      appearance="filled-outlined"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      pill
      appearance="filled-outlined"
      variant="danger"
      >Danger</l-badge
    >
  </div>
  <div class="flex flex-wrap items-center gap-2">
    <span class="text-sm text-tertiary w-28">Accent</span>
    <l-badge
      pill
      appearance="accent"
      >Default</l-badge
    >
    <l-badge
      pill
      appearance="accent"
      variant="info"
      >Info</l-badge
    >
    <l-badge
      pill
      appearance="accent"
      variant="success"
      >Success</l-badge
    >
    <l-badge
      pill
      appearance="accent"
      variant="warning"
      >Warning</l-badge
    >
    <l-badge
      pill
      appearance="accent"
      variant="danger"
      >Danger</l-badge
    >
  </div>
</div>

Sizes

Add size="sm" or size="lg". Default is md.

Small Medium Large
Code
html
<l-badge size="sm">Small</l-badge>
<l-badge>Medium</l-badge>
<l-badge size="lg">Large</l-badge>

Variants

Add variant="info", variant="success", variant="warning", or variant="danger". Default is neutral.

Neutral Info Success Warning Danger
Code
html
<l-badge>Neutral</l-badge>
<l-badge variant="info">Info</l-badge>
<l-badge variant="success">Success</l-badge>
<l-badge variant="warning">Warning</l-badge>
<l-badge variant="danger">Danger</l-badge>

Examples

Categorical color

The variants say how something went. When the color instead says what kind of thing this is — a site, a department, an asset class — give the badge your own class and set --text-color, --background-color and --border-color on it.

The border is a 30% tint of the label color, so --text-color alone is the whole theme on an outlined badge; --background-color adds the fill, and --border-color replaces the derivation when your palette carries its own line token. All three win over variant and appearance, so a tinted badge keeps its tint through an appearance change. Every CSS custom property inherits, so setting them on a wrapper themes each badge inside.

Keep variant for the four interface states. A business family belongs in your own class, where it cannot collide with a variant the library adds later.

Lyon branch Facilities MX-3070-014
Code
html
<style>
  /* Your own families. `--text-color` carries the border with it, so an outlined
     chip needs one declaration; a filled one adds `--background-color`.

     These stand in for a consumer's token families. The point is that they are
     not interface states: the emerald here means "this is a place", not
     "success" — and the day one of the two moves, the other can stay. */
  .chip-site {
    --text-color: light-dark(oklch(45% 0.11 165), oklch(87% 0.09 165));
    --background-color: light-dark(oklch(95% 0.04 165), oklch(28% 0.05 165));
  }
  .chip-department {
    --text-color: light-dark(oklch(46% 0.1 95), oklch(88% 0.1 95));
    --background-color: light-dark(oklch(96% 0.05 95), oklch(29% 0.06 95));
  }
  .chip-machine {
    --text-color: light-dark(oklch(48% 0.12 250), oklch(87% 0.09 250));
  }
</style>

<div class="flex flex-wrap items-center gap-2">
  <l-badge class="chip-site">
    <l-icon name="mdi:map-marker-outline"></l-icon>
    Lyon branch
  </l-badge>
  <l-badge class="chip-department">
    <l-icon name="mdi:sitemap-outline"></l-icon>
    Facilities
  </l-badge>
  <l-badge class="chip-machine">MX-3070-014</l-badge>
</div>

Accessibility

Criteria

Color contrast

Text and background meet minimum contrast ratio across all appearances and variants

WCAG1.4.3
RGAA3.2
Non-text contrast

Badge borders meet non-text contrast minimum against adjacent surfaces

WCAG1.4.11
RGAA3.3
Not color alone

Do not rely on badge color alone to convey status — always include a text label

WCAG1.4.1
RGAA3.1

Rules

  • Always include visible text inside the badge — do not use color alone to convey meaning
  • When a badge conveys dynamic status, wrap it in a role="status" container so screen readers announce changes
  • Verify a custom --text-color / --background-color pair yourself — the built-in variants are contrast-checked, a consumer palette is not

API reference

Importing

js
import 'luxen-ui/badge';
css
@import 'luxen-ui/css/badge';

Attributes & Properties

variantBadgeVariant | undefinedProperty
Style variant: info, success, warning, danger, or neutral (default)
pillbooleandefault:falseProperty
Display as pill shape
sizeBadgeSize | undefinedProperty
Badge size: sm, lg. Default is md.
appearanceBadgeAppearance | undefinedProperty
Visual appearance: filled, filled-outlined, accent. Default is outlined.

CSS custom properties

--text-colorCustom property
Label color. The border is a tint of it, so this alone repaints an outlined badge. Defaults to the variant step.
--background-colorCustom property
Badge fill. Defaults to the appearance step — transparent when outlined.
--border-colorCustom property
Badge border. Defaults to a 30% tint of --text-color; setting it replaces that derivation and holds through appearance="filled", whose default line is transparent.
--border-radiusdefault:--l-radius-mdCustom property
Corner radius. The corner stays a squircle; pill is what trades it for a true arc.