Navigation

v0.0.4
Content

Badge

A small chip for a status, a category or a count.

On this page

A badge is a small chip for a status, a category or a count. Neutral badges carry most labels; hue appears only when the badge states a status, and always beside words that say the same thing.

Badge

<span class="badge">Draft</span><span class="badge badge-success badge-dot">Published</span>

#Variants

Variants

<span class="badge">Chip</span><span class="badge badge-outline">Outline</span><span class="badge badge-raised">Raised</span><span class="badge badge-ink">Ink</span>

#Status

Status

<span class="badge badge-info badge-dot">Queued</span><span class="badge badge-success badge-dot">Ready</span><span class="badge badge-warning badge-dot">Degraded</span><span class="badge badge-danger badge-dot">Failed</span>

#Live

badge-live makes the dot send out a ring, for something that is happening now: a recording, a deployment in progress, a stream. Use it for one thing on a view; a page of pulsing dots says nothing. With reduced motion it is a plain dot.

Live

<span class="badge badge-success badge-dot badge-live">Live</span><span class="badge badge-danger badge-dot badge-live">Recording</span><span class="badge badge-dot">Idle</span>

#Sizes and shape

Sizes and shape

<span class="badge badge-sm">Small</span><span class="badge">Medium</span><span class="badge badge-lg">Large</span><span class="badge badge-pill">Pill</span><span class="badge badge-ink badge-pill">12</span>

#On an icon

badge-corner places a count on the corner of its nearest positioned parent and cuts it out with a ring in the color of the surface it sits on, which it reads from --surface-color. Set --badge-ring on a background of your own. Describe the count in the parent's accessible name.

On an icon

<button type="button" class="btn btn-square relative" aria-label="Notifications, 3 unread">  <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">    <path d="M10 5a2 2 0 1 1 4 0a7 7 0 0 1 4 6v3a4 4 0 0 0 2 3h-16a4 4 0 0 0 2-3v-3a7 7 0 0 1 4-6" />    <path d="M9 17v1a3 3 0 0 0 6 0v-1" />  </svg>  <span class="badge badge-ink badge-corner" aria-hidden="true">3</span></button>

#Classes

ClassDescription
badgeA neutral chip, 22px tall
badge-sm18px tall; the default is 22px. With badge
badge-lg26px tall; the default is 22px. With badge
badge-pillFully rounded ends. With badge
badge-outlineA contour only, with no fill. With badge
badge-raisedA small raised sheet, for a badge that sits on a busy surface. With badge
badge-inkSolid ink with inverse text. With badge
badge-infoA wash of the info hue. With badge
badge-successA wash of the success hue. With badge
badge-warningA wash of the warning hue. With badge
badge-dangerA wash of the danger hue. With badge
badge-dotA leading 6px dot in the badge's tone. With badge
badge-liveWith badge-dot: the dot sends out a ring, for something happening now. With reduced motion it is a plain dot. With badge
badge-cornerA count on the corner of its nearest positioned parent, cut out by a ring of the surface it sits on. Describe the count in the parent's accessible name. With badge

#Custom properties

PropertyDefaultDescription
--badge-ringColor of the ring around a badge-corner. It is not declared: it falls back to --surface-color, then to --color-surface-base

#Source

@master/ui/components/badge.css
/* Badge: a small chip for a status, a category or a count. Hue appears only with a status. */@layer components {  .badge {    --badge-height: 1.375rem;    --badge-padding-x: .4375rem;    --badge-font-size: .71875rem;    --badge-radius: var(--radius-chip);    --badge-tone: var(--color-text-muted);    --icon-size: .875rem;    --icon-offset: -.0625rem;    display: inline-flex;    flex-shrink: 0;    align-items: center;    justify-content: center;    gap: .3125rem;    height: var(--badge-height);    min-width: var(--badge-height);    padding: 0 var(--badge-padding-x);    border-radius: calc(var(--badge-radius) * var(--corner-scale));    corner-shape: var(--corner-shape);    background: var(--color-surface-chip);    color: var(--color-text-body);    box-shadow: inset 0 0 0 .5px var(--color-line-contour);    font: var(--font-weight-control) var(--badge-font-size)/1 var(--font-family-sans);    font-variant-numeric: tabular-nums;    letter-spacing: 0;    white-space: nowrap;    /* A badge may be a link, such as the announcement over a hero; it never takes a link's underline. */    text-decoration: none;    vertical-align: middle;    &.badge-sm {      --badge-height: 1.125rem;      --badge-padding-x: .3125rem;      --badge-font-size: .65625rem;      --icon-size: .75rem;      --badge-radius: calc(var(--radius-chip) - 1px);      gap: .25rem;    }    &.badge-lg {      --badge-height: 1.625rem;      --badge-padding-x: .5625rem;      --badge-font-size: .78125rem;      --icon-size: 1rem;      --badge-radius: calc(var(--radius-chip) + 1px);    }    &.badge-pill {      --badge-radius: 999px;      corner-shape: round;      padding-inline: calc(var(--badge-padding-x) + 1px);    }    &.badge-outline {      background: transparent;      box-shadow: inset 0 0 0 .5px var(--color-line-strong);    }    /* Raised: a small sheet, for a badge that sits on a busy surface. */    &.badge-raised {      @apply --surface-sheet;      color: var(--color-text-strong);      box-shadow: var(--shadow-raised);    }    &.badge-ink {      --badge-tone: currentColor;      background: var(--color-surface-inverse);      color: var(--color-text-inverse);      box-shadow: inset 0 .5px 0 var(--color-ink-highlight), 0 0 0 .5px var(--color-ink-edge);    }    &:is(.badge-info, .badge-success, .badge-warning, .badge-danger) {      background: color-mix(in oklab, var(--badge-tone) 8%, var(--color-surface-raised));      color: color-mix(in oklab, var(--badge-tone) 82%, var(--color-text-strong));      box-shadow: inset 0 0 0 .5px color-mix(in oklab, var(--badge-tone) 36%, transparent);    }    &.badge-info { --badge-tone: var(--color-info); }    &.badge-success { --badge-tone: var(--color-success); }    &.badge-warning { --badge-tone: var(--color-warning); }    &.badge-danger { --badge-tone: var(--color-danger); }    /* A leading status dot in the badge's tone. */    &.badge-dot::before {      content: '';      flex: none;      width: 6px;      height: 6px;      border-radius: 999px;      background: var(--badge-tone);    }    /* Live: the dot of something happening now sends out a ring. Without motion it is a plain dot. */    &.badge-live::before {      animation: badge-live 1.8s var(--easing-glide) infinite;    }    @media (prefers-reduced-motion: reduce) {      &.badge-live::before {        animation: none;      }    }    /* A count on the corner of its nearest positioned parent, cut out by a ring of the surface it sits on. */    &.badge-corner {      --badge-height: 1.125rem;      corner-shape: round;      --badge-padding-x: .3125rem;      --badge-font-size: .65625rem;      --badge-radius: 999px;      position: absolute;      top: 0;      inset-inline-end: 0;      translate: 35% -35%;      outline: 2px solid var(--badge-ring, var(--surface-color, var(--color-surface-base)));      /* It hangs off the end corner, whichever side that is. */      &:dir(rtl) {        translate: -35% -35%;      }    }    @media (forced-colors: active) {      outline: 1px solid CanvasText;      outline-offset: -1px;    }  }}@keyframes badge-live {  from {    box-shadow: 0 0 0 0 color-mix(in oklab, var(--badge-tone) 45%, transparent);  }  70%, to {    box-shadow: 0 0 0 5px transparent;  }}