Components
Badge
A badge is a small status indicator that can be placed on other elements.
Use thelabel property to add content inside the Badge.
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="anchor 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator"></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="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="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><script type="module"> function o() { const c = document.querySelectorAll("#badge-visibility-toggle"), n = new Set(); c.forEach((e) => { const t = e.closest(".example-container"); t && t.querySelectorAll(".badge").forEach((i) => n.add(i)); }); function a(e) { (n.forEach((t) => { t.classList.toggle("invisible", e); }), c.forEach((t) => { t.checked !== e && (t.checked = e); })); } (c.forEach((e) => { e.addEventListener("change", () => a(e.checked)); }), c.length > 0 && a(c[0].checked)); } o(); document.addEventListener("astro:after-swap", o);</script><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="5">5</span> </span></span><span class="anchor badge dot 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="anchor-floating"> <span class="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="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="35">35</span> </span></span><span class="anchor 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="anchor-floating"> <span class="badge-indicator" aria-label="99+">99+</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="OK!">OK!</span> </span></span><span class="anchor badge 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="anchor-floating"> <span class="badge-indicator" aria-label="3K">3K</span> </span></span>Anatomy
The badge component is composed of two main elements:
- Element to wrap
- Badge
5
API
| Prop | Type | Default | Description |
|---|---|---|---|
alignment | "start-start" | "start-end" | "end-start" | "end-end" | "start-end" | Position of the badge relative to its container. |
color | "critical" | "ok" | "good" | "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 | - | Screen reader label for the badge. |
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(.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). */ &>.anchor-floating:not([popover]) { inset: var(--_badge-inset); position-anchor: auto; position-area: none; }
/* Indicator */ &>.anchor-floating>.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 */ &.critical { --_bg-color: var(--critical); --_border-color: var(--critical); }
&.success { --_bg-color: var(--success); --_border-color: var(--success); }
&.info { --_bg-color: var(--info); --_border-color: var(--info); }
&.warning { --_bg-color: var(--warning); --_border-color: var(--warning); }
&.neutral { --_bg-color: var(--neutral); --_border-color: var(--neutral); }
/* Alignment */ &.start-start { --_anchor-tx: 50%; --_anchor-ty: 50%; --_badge-inset: auto 100% 100% auto; }
&.end-start { --_anchor-tx: 50%; --_anchor-ty: -50%; --_badge-inset: 100% 100% auto auto; }
&.end-end { --_anchor-tx: -50%; --_anchor-ty: -50%; --_badge-inset: 100% auto auto 100%; }
/* Dot */ &.dot { --_anchor-tx: calc((var(--_dot-size) - 2px) * -1); --_anchor-ty: var(--_dot-size); }
&.dot>.anchor-floating>.badge-indicator { block-size: var(--_dot-size); inline-size: var(--_dot-size); min-inline-size: var(--_dot-size); padding: 0; }
/* Visibility */ &.invisible>.anchor-floating>.badge-indicator { opacity: 0; pointer-events: none; } }}@layer components.root { :where(.anchor) { anchor-name: --anchor; anchor-scope: --anchor; display: inline-block; inline-size: fit-content;
/* Always-visible */ &>.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 */ &>.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); } }}