Data Display · astro-ui · Badge
Badge
Status/count label — inline or overlay bubble with icon, dot, avatar, and dismiss.
Badge is a zero-JS status and count label. Inline it next to text, or use it as an overlay bubble pinned to another element’s corner with content + position. Inline badges compose: an icon slot (or any image, e.g. a flag) sized via –aui-badge-icon, a variant-tinted status dot, optically aligned avatars, and a labeled dismiss button. Counts stay real text so screen readers announce them.
Features
- 11 variants incl. soft, muted, destructive
- 5 sizes: xs → 2xl
- Overlay bubble mode with 4 corner positions
- Icon slot, status dot, avatar alignment, dismiss button
- content prop for counts (keeps text announcement)
- Logical-property positioning — mirrors in RTL
Usage
---
import { Badge } from "astro-ui";
---
<Badge variant="success">Active</Badge>
<Badge content="3" position="top-right" variant="destructive" ariaLabel="3 notifications" />
InboxDemos
Variants
<Badge>Primary</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="outline">Outline</Badge>
<Badge variant="success">Active</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="destructive">Failed</Badge>
<Badge variant="info">New</Badge>Sizes
<Badge size="sm">sm</Badge>
<Badge size="md">md</Badge>
<Badge size="lg">lg</Badge>
<Badge size="xl">xl</Badge>Badge with icon
Anything in the icon slot is boxed at--aui-badge-icon (default 0.875em) and scales with the badge size.
<Badge variant="outline" size="lg">
<svg slot="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M20 6L9 17l-5-5" />
</svg>
Verified
</Badge>
<Badge variant="soft" size="lg">
<svg slot="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<circle cx="12" cy="12" r="10" />
<path d="M12 8v4M12 16h.01" />
</svg>
Action required
</Badge>Badge with status dot
The dot inherits the variant's text color — set it and forget it.
<Badge variant="success" dot>Operational</Badge>
<Badge variant="warning" dot>Degraded</Badge>
<Badge variant="destructive" dot>Outage</Badge>Badge with avatar
Drop an Avatar in the default slot — optical alignment against the pill padding is built in.
<Badge variant="outline" size="xl">
<Avatar name="Ada Lovelace" size="xs" />
Ada
</Badge>
<Badge variant="muted" size="xl">
<Avatar name="Grace Hopper" size="xs" status="online" />
Grace
</Badge>Badge with flag image
Pass a flag through the icon slot and size it via --aui-badge-icon.
<Badge variant="outline" size="lg" style="--aui-badge-icon: 1rem">
<img slot="icon" src="/flags/us.svg" alt="" width="16" height="16" style="border-radius: 2px" />
United States
</Badge>
<Badge variant="outline" size="lg" style="--aui-badge-icon: 1rem">
<img slot="icon" src="/flags/de.svg" alt="" width="16" height="16" style="border-radius: 2px" />
Germany
</Badge>Badge with dismiss button
closable renders a labeled, focusable × button — Badge stays zero-JS, so wire the removal app-side.
<Badge variant="outline" size="lg" closable>Design</Badge>
<Badge variant="outline" size="lg" closable closeLabel="Remove Research filter">Research</Badge>
<Badge variant="soft" size="lg" closable>Docs</Badge>Overlay bubble
The bubble anchors to the marked parent (position: relative) — place the Badge inside any positioned element. A dot bubble renders when no content is passed.
<span class="relative inline-block">
<Badge position="top-right" content="3" variant="destructive" ariaLabel="3 items" />
Inbox
</span>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "secondary" | "outline" | "ghost" | "soft" | "success" | "warning" | "info" | "muted" | "destructive" | "primary" | Color scheme. |
size | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | Font/padding scale. |
content | string | — | Count/content when no default slot is provided. |
position | "top-right" | "top-left" | "bottom-right" | "bottom-left" | — | Overlay bubble corner (logical start/end — mirrors in RTL). |
contentProps | Record<string, any> | {} | Forwarded to the bubble element. |
dot | boolean | false | Leading status dot tinted by the variant (inline mode). |
closable | boolean | false | Renders an accessible dismiss button (inline mode). |
closeLabel | string | "Dismiss" | Accessible label for the dismiss button. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Element id. |
ariaLabel | string | — | Accessible name. |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Status changes announced via
aria-labelon status badges - Purely presentational by default — no extra semantics to announce
FAQ
How do screen readers handle counts?
The count is real text inside the badge. Add ariaLabel for context, e.g. ariaLabel="3 unread messages".
Does the dismiss button remove the badge?
No — Badge ships zero JS. The button is real, focusable, and labeled via closeLabel; wire the removal with a small script or a form action on your side.
How do I put an image or flag inside a badge?
Anything in the icon slot is boxed at --aui-badge-icon (default 0.875em) and scales with the badge. Set the variable inline, e.g. style="--aui-badge-icon: 1rem", for a 16px flag.
Changelog
Version history mentioning Badge.
- Data display (10): Badge, Avatar, Attachment, Table, Progress, Bubble, Chart, Empty, Tag, Timeline.