Components
Badge
A badge is a small status indicator that can be placed on other elements.
Full support Supported since v144. Full support Supported since v148. Full support Supported since v26.
Variants
Default, and dot.
5
---import { Badge } from "@opui/astro"---
<Badge label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge>
<Badge dot> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><span class="ui-anchor ui-badge" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-dot" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator"> </span> </span></span>Indicator
Set indicator text with the label prop or the indicator slot. The default slot holds the anchored element.
5
99+
---import { Badge } from "@opui/astro"---
<Badge label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge>
<Badge> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg > <span slot="indicator">99+</span></Badge><span class="ui-anchor ui-badge" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator"> <span>99+</span> </span> </span></span>Severities
critical, info, neutral, success, warning.
5
5
5
5
5
---import { Badge } from "@opui/astro"---
<Badge color="critical" label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge color="info" label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge color="success" label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge color="warning" label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge color="neutral" label="5"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><span class="ui-anchor ui-badge ui-critical" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-info" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-success" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-warning" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-neutral" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span>Visibility
Change the badge's visibility using the invisible
prop.
5
---import { Badge } from "@opui/astro"---
<Badge label="5" invisible> <!-- --></Badge>
<Badge dot invisible> <!-- --></Badge><span class="ui-anchor ui-badge ui-invisible" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="5"> 5 </span> </span></span><span class="ui-anchor ui-badge ui-dot ui-invisible" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator"> </span> </span></span>Alignment
Where the badge should be placed over the child.
start-start, default,
end-start, end-end.
35
99+
OK!
3K
---import { Badge } from "@opui/astro"---
<Badge alignment="start-start" label="35"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge label="99+"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge alignment="end-start" label="OK!"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><Badge alignment="end-end" label="3K"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" ><path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path></svg ></Badge><span class="ui-anchor ui-badge ui-start-start" style=" --anchor-position-area: start start; --_anchor-inset: auto 100% 100% auto; "> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="35"> 35 </span> </span></span><span class="ui-anchor ui-badge" style=""> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="99+"> 99+ </span> </span></span><span class="ui-anchor ui-badge ui-end-start" style=" --anchor-position-area: end start; --_anchor-inset: 100% 100% auto auto; "> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="OK!"> OK! </span> </span></span><span class="ui-anchor ui-badge ui-end-end" style="--anchor-position-area: end end; --_anchor-inset: 100% auto auto 100%"> <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" > <path fill="currentColor" d="M2.004 9.303A4.5 4.5 0 0 1 6.5 5h19a4.5 4.5 0 0 1 4.496 4.303l-1.476.82L16 16.864L3.48 10.123zM2 11.588V22.5A4.5 4.5 0 0 0 6.5 27h19a4.5 4.5 0 0 0 4.5-4.5V11.588l-.526.293l-13 7a1 1 0 0 1-.948 0L2.514 11.874z" ></path> </svg> <span class="ui-anchor-floating"> <span class="ui-badge-indicator" aria-label="3K"> 3K </span> </span></span>Anatomy
The badge is composed of an anchored element (default slot), and an
indicator (label prop or indicator slot).
5
API
| Prop | Type | Default | Description |
|---|---|---|---|
alignment | "start-start", "end-start", "end-end" | - | Position of the badge relative to its container. Omit for the default (centered on the end edge). |
color | "critical", "info", "neutral", "success", "warning" | - | The color variant of the badge. |
dot | boolean | false | Renders the badge as a simple dot. |
invisible | boolean | false | Hides the badge. |
label | string | number | - | Visible badge text. Also sets aria-label on the indicator. |
Slots
| Slot | Description |
|---|---|
| default | The element the badge is anchored to. |
indicator | Badge indicator content. Alternative to the label prop. |
Browser support
Full support Supported since v144. Full support Supported since v148. Full support Supported since v26.
See also the full browser support guide.
Installation
Dependencies
@layer components.extended { :where(.ui-badge) { --_anchor-tx: -50%; --_anchor-ty: 50%; --_badge-inset: auto auto 100% 100%; --_bg-color: var(--primary); --_border-color: var(--primary); --_dot-size: var(--size-2); --_size: var(--size-4); --_text-color: var(--gray-1);
display: inline-flex; position: relative; vertical-align: middle;
/* Floating wrapper: traditional inset-based positioning so this works in browsers without position-area support (Firefox, older Safari). */ & > .ui-anchor-floating:not([popover]) { inset: var(--_badge-inset); position-anchor: auto; position-area: none; }
/* Indicator */ & > .ui-anchor-floating > .ui-badge-indicator { background-color: var(--_bg-color); block-size: var(--_size); border: 2px solid var(--_border-color); border-radius: var(--radius-round); color: var(--_text-color); display: grid; font-size: 12px; font-weight: 500; inline-size: max-content; line-height: normal; min-inline-size: var(--_size); padding-inline: var(--size-1); place-items: center; text-align: center; transition: opacity 0.2s var(--ease-out-1); }
/* Colors */ &.ui-critical { --_bg-color: var(--critical); --_border-color: var(--critical); }
&.ui-success { --_bg-color: var(--success); --_border-color: var(--success); }
&.ui-info { --_bg-color: var(--info); --_border-color: var(--info); }
&.ui-warning { --_bg-color: var(--warning); --_border-color: var(--warning); }
&.ui-neutral { --_bg-color: var(--neutral); --_border-color: var(--neutral); }
/* Alignment */ &.ui-start-start { --_anchor-tx: 50%; --_anchor-ty: 50%; --_badge-inset: auto 100% 100% auto; }
&.ui-end-start { --_anchor-tx: 50%; --_anchor-ty: -50%; --_badge-inset: 100% 100% auto auto; }
&.ui-end-end { --_anchor-tx: -50%; --_anchor-ty: -50%; --_badge-inset: 100% auto auto 100%; }
/* Dot */ &.ui-dot { --_anchor-tx: calc((var(--_dot-size) - 2px) * -1); --_anchor-ty: var(--_dot-size); }
&.ui-dot > .ui-anchor-floating > .ui-badge-indicator { block-size: var(--_dot-size); inline-size: var(--_dot-size); min-inline-size: var(--_dot-size); padding: 0; }
/* Visibility */ &.ui-invisible > .ui-anchor-floating > .ui-badge-indicator { opacity: 0; pointer-events: none; } }}@layer components.root { :where(.ui-anchor) { anchor-name: --anchor; anchor-scope: --anchor; display: inline-block; inline-size: fit-content;
/* Always-visible */ & > .ui-anchor-floating:not([popover]) { block-size: max-content; inline-size: max-content; position: absolute; position-anchor: --anchor; position-area: var(--anchor-position-area, start end); translate: var(--_anchor-tx, 0) var(--_anchor-ty, 0); }
/* Hover-triggered */ & > .ui-anchor-floating[popover] { inset: unset; margin: 0; position: absolute; position-area: var(--anchor-position-area, start end); translate: var(--_anchor-tx, 0) var(--_anchor-ty, 0); } }}