---
outline: deep
---

# 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>
```

**`<l-badge>`** — Custom Element (no Shadow DOM)

> **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>`](/elements/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).

```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.

```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.

```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.

```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.

```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.

```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
- **Non-text contrast** — Badge borders meet non-text contrast minimum against adjacent surfaces
- **Not color alone** — Do not rely on badge color alone to convey status — always include a text label

### 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

- **variant**: `BadgeVariant | undefined` — Style variant: `info`, `success`, `warning`, `danger`, or `neutral` (default)
- **pill**: `boolean` (default: `false`) — Display as pill shape
- **size**: `BadgeSize | undefined` — Badge size: `sm`, `lg`. Default is md.
- **appearance**: `BadgeAppearance | undefined` — Visual appearance: `filled`, `filled-outlined`, `accent`. Default is outlined.

### CSS custom properties

- `--text-color` — Label color. The border is a tint of it, so this alone repaints an outlined badge. Defaults to the `variant` step.
- `--background-color` — Badge fill. Defaults to the `appearance` step — transparent when outlined.
- `--border-color` — 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-radius` (default: `--l-radius-md`) — Corner radius. The corner stays a squircle; `pill` is what trades it for a true arc.
