Badge
A numeric/status badge, typically used for message counts or new-content indicators.
Basic usage
Numeric badges
Max display
When the value exceeds max, max+ is displayed.
Max display
Dot
Status dot
Zero value
0 is hidden by default; shown when showZero is set.
Zero value control
Standalone badge
When no child content is wrapped, the badge falls back from the "top-end corner" position to a static inline element (never collapses), so it can sit in a text flow or a menu row.
Standalone badge
Icon badge
icon takes an icon name (lookup prefers custom registrations, falling back to the built-in icon set) and renders a small icon inside the badge (e.g. a √ / ! status corner). It is mutually exclusive with value / dot: icon wins and shows the icon instead of a number/dot; an invalid icon name silently falls back to the numeric logic.
Icon badges
Badge colors
color accepts the four semantic colors (primary / success / warning / danger), any CSS color value, and the 11 preset names (magenta / red / volcano / orange / gold / lime / green / cyan / blue / geekblue / purple, mapped to --oas-preset-* tokens, auto-brightened in dark). It works uniformly across count / dot / ribbon modes; the solid text color uses a fixed text-on-* token for semantic/preset colors, and is picked black/white by background luminance only for arbitrary CSS color values.
count semantic colors
count preset colors
count / dot custom colors
Outline variant
variant="outline" switches to an outlined badge: a transparent background with the border and text following the color semantics (solid filled is the default; invalid values fall back). Good for stacking on images/colored surfaces; composes with the bordered white ring.
outline variant
Offset
offset="x,y" (px numbers) shifts the corner badge from its default position; x is positive rightward and y positive downward (screen coordinates, independent of the corner direction). Invalid values (non-numeric, missing coordinate) are silently ignored. It composes with corner: pick the corner first, then fine-tune.
Offset
Corner placement
corner pins the badge to one of the four corners of the host: top-right (default) / top-left / bottom-right / bottom-left; invalid values silently fall back to top-right. offset is a precise fine-tune on top of the corner result (corner first, then shift; they compose).
Four corners
corner + offset
Circular overlap
When wrapping circular content (e.g. an avatar), add overlap so the badge tucks inside the circle edge: the translate amount shrinks from 50% to ~29% (the 1-√2/2 geometric inset). Only affects corner badge mode.
overlap circular inset
White outline
bordered adds a 2px background-color ring around the badge (box-shadow: 0 0 0 2px var(--oas-color-bg)) so it stands out against complex backgrounds like avatars/images; visual-only, never changes positioning (composes with corner / offset / overlap).
bordered white outline
Status point
status renders an inline standalone element of "status dot + text" (not a corner badge) and is mutually exclusive with ribbon / dot / count modes (rendered first when set). The processing dot pulses (prefers-reduced-motion disables it).
Status points
Size tiers
size provides three tiers: small (compact, numeric badge ~13px tall, dot 6px) / medium (default, ~16px, dot 8px) / large (~20px, dot 10px); invalid values silently fall back to medium.
Size tiers small / medium / large
Attention animation
attention="pulse" makes the badge emit a periodic outward pulse ring (the pulse color can be customized via --oas-badge-pulse-color, defaulting to the badge background); attention="bounce" makes the badge bounce up and down slightly. It only applies to count / dot / standalone badges (the ribbon is unaffected) and is disabled under prefers-reduced-motion.
pulse
bounce
Native tooltip
Adding the native title attribute to the badge host gives a hover tooltip with zero JS.
Native tooltip
Dynamic increment
value updates take effect immediately; the host can add an animation class on click for a transition feedback (this example uses ::part(badge) for a scale/opacity micro-animation).
The numeric badge carries role="status" + aria-live="polite" + aria-atomic="true": whenever the number (including the max-truncated display value) changes, it announces via aria-label using the locale (e.g. "5 unread notifications") — no extra JS required.
Dynamic increment
Ribbon corner
The ribbon boolean attribute (or mode="ribbon") enables a ribbon corner — an angled folded ribbon on the top edge of the wrapped content. Text is provided via the text attribute; it sits at the inline-end (placement="end") by default and can be moved to placement="start".
Basic ribbon
Default ribbon (top-end)
mode="ribbon" (top-start)
Ribbon position
ribbon-position controls the ribbon's vertical position: hang (default, hangs below the top edge) / edge (flush with the top edge) / cross (straddles the top edge, pressing against the card border for the strongest wrap-around feel). All three positions are orthogonal to placement (start / end) and work on both sides.
Ribbon position
hang (default, hangs below)
edge (flush with top edge)
cross (straddling top edge)
Ribbon position (placement=start, left side)
hang (hangs below)
edge (flush with top edge)
cross (straddling top edge)
Ribbon forms
ribbon-form switches the ribbon shape: fold (default, straight band + folded corner) / diagonal (45° diagonal band sweeping from the top corner; the band extends outside the card, so the host needs overflow: hidden to clip it) / triangle (a pure corner triangle holding a small icon or slot="ribbon" content) / bookmark (a vertical tab hanging from the top edge with a swallow-tail notch) / side (a vertical strip hung at mid-height of the side edge) / seal (a circular serrated stamp with centered text) / banner (a full-width strip across the top edge with angled ends) / flag (a side swallow-tail banner: a horizontal band with a V notch at the card-facing end; the outer end stays flush with the card edge, and the notch always faces the card-inner end). Invalid values silently fall back to fold. ribbon-direction controls the notch direction of bookmark (down default, hanging from the top edge / left, tab on the right edge with the notch pointing left / right, tab on the left edge with the notch pointing right; physical-direction semantics, not flipped in RTL), and only takes effect for bookmark; ribbon-vertical controls the vertical position of the side-mount forms (center default, vertically centered / top, flush with the top edge / bottom, flush with the bottom edge). ribbon-size offers sm (default) / md / lg tiers for diagonal (a tier only changes the fallback band height / font size / pin depth; host --oas-badge-diagonal-* custom properties take precedence). The ribbon-position vertical trio only affects the fold shape; the other shapes have their own vertical placement. offset fine-tunes the position of every ribbon shape (offset="x,y" px shift, negative values allowed). rolled is a boolean modifier that adds an end roll (a large end radius + an inner gradient darkening that reads as a rolled cylinder); it composes with fold / flag / rounded / zigzag / arrow (banner keeps its own angled ends and gets no roll; diagonal / triangle / bookmark / side / seal silently ignore it).
Ribbon forms
fold
triangle
bookmark
bookmark direction=left (notch left)
bookmark direction=right (notch right)
bookmark left + vertical=top
bookmark right + vertical=bottom
side
seal
banner
flag (side swallow-tail)
rounded
zigzag
arrow
fold + rolled end
ribbon-size offers three tiers for diagonal (sm default / md / lg); a tier only changes the fallback band height, font size and pin depth. The host can override --oas-badge-diagonal-height / --oas-badge-diagonal-font / --oas-badge-diagonal-pin / --oas-badge-diagonal-text-inset custom properties, which take precedence over the tier.
diagonal size tiers sm / md / lg
offset fine-tunes the position of every ribbon shape: offset="x,y" shifts by px on top of the shape's own anchor (x positive rightward, y positive downward, negative values allowed), composing orthogonally with placement / ribbon-position / ribbon-vertical.
Ribbon offset fine-tune
bookmark left + offset=0,20
fold + offset=0,-8
ribbon-anchor unifies the ribbon anchor, with the anchor set adapted per shape semantics (industry practice: shape and position are bound together):
- diagonal / triangle: four corners only
- fold / side / banner / seal / bookmark / flag (and the remaining shapes): all 8 positions (4 edge centers + 4 corners) Anchors pin the ribbon to an edge/corner (the fold notch auto-flips on bottom anchors), and
offsetfine-tunes any arbitrary position.
Ribbon anchors: angular corners
Ribbon anchors: fold positions (hug left/right)
fold left (edge center)
fold right (edge center)
fold bottom-left (notch flipped)
fold bottom-right (notch flipped)
Premium metallic
premium adds a metallic gold treatment to the ribbon: a multi-stop light-gold-to-dark-gold gradient with a deep-gold fine outline (clipped shapes get the outline traced along their clip-path silhouette), and the text color is fixed to near-black #1a1a1a. It composes orthogonally with color with the priority premium > color > semantic default, and works with every ribbon-form; dark theme adapts automatically (driven by the --oas-preset-gold token).
Premium metallic
premium fold
premium overrides color
premium bookmark
premium seal
premium banner
Colored ribbon
color supports the four semantic colors primary / success / warning / danger, following the theme (light/dark); preset names and arbitrary color values are also supported (injected via --oas-preset-* tokens / the raw value).
Colored ribbon
primary
success
warning
danger
Ribbon preset & custom colors
geekblue
#7c3aed
Custom ribbon content
Besides the text attribute, arbitrary content can be passed through slot="ribbon" (the slot takes precedence when present).
Custom content
Custom content via slot="ribbon"
Comparison with count / dot
The same oas-badge can serve as a count badge or a ribbon: the count badge is a small number pinned to the top-end corner, dot is a textless status point, while the ribbon spans the top edge of the wrapped content; status is a standalone inline "dot + text" element.
count / dot / ribbon comparison
count numeric badge
dot status point
ribbon
Badge Shape
shape controls the badge shape: round (default, rounded — the base class, no extra class written) / square (right angles) / pill (capsule, fully rounded ends). It applies to both numeric badges and dot points: square turns a dot into a square point, while pill keeps it circular; invalid values silently fall back to round.
shape: round / square / pill
Loading Badge (composed with oas-spin)
The badge itself has no built-in spinner prop — put an oas-spin in the default slot to express "badge containing a loading ring": the corner count / dot / status point still come from oas-badge, while the indicator's form (variant) and size (size) are controlled independently by oas-spin, letting you compose them freely.
Corner badge + loading ring (composed with oas-spin)
API
oas-badge
Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
attention | Attention animation: pulse (an outward pulse ring; the pulse color follows the --oas-badge-pulse-color custom property, defaulting to the badge background) / bounce (slight up-and-down bounce); applies only to count / dot / standalone badges (the ribbon is unaffected) and is disabled under prefers-reduced-motion | BadgeAttention | — |
bordered | White outline: boolean, adds a 2px background-color ring around the badge (box-shadow: 0 0 0 2px var(--oas-color-bg)) to separate it from an avatar/image background; visual-only, never changes positioning (composes with corner/offset/overlap) | boolean | — |
color | Badge color: the four semantic colors (primary / success / warning / danger), any CSS color value, or one of the 11 preset names (magenta / red / volcano / orange / gold / lime / green / cyan / blue / geekblue / purple, mapped to --oas-preset-* tokens, auto-brightened in dark). Applies uniformly across count / dot / ribbon; the solid text color uses a fixed text-on-* token for semantic/preset colors, and is picked black/white by background luminance only for arbitrary CSS color values | BadgeColor | BadgePresetColor | — |
corner | Corner placement: top-right (default) / top-left / bottom-right / bottom-left, affects count / dot corner badges only (the ribbon uses placement); offset fine-tunes in screen px on top of the corner result (x positive rightward, y positive downward, independent of the corner direction), corner first then shift, they compose; invalid values silently fall back to top-right | BadgeCorner | top-right |
dot | Dot mode | boolean | — |
icon | In-badge icon: a built-in icon name (e.g. check / warning), rendered as an inline SVG (1em following the badge font size, decorative and hidden from screen readers); mutually exclusive with value/dot (icon wins) | string | — |
max | Upper limit | string | — |
mode | Mode: count (default, numeric/dot badge) or ribbon (ribbon corner, same as ribbon attribute) | BadgeMode | count |
offset | Position fine-tune: "x,y" (px numbers, negative values allowed), shifts the corner badge or ribbon on top of its anchor position (x positive rightward, y positive downward); composes with corner / placement / ribbon-vertical (anchor first, then shift); invalid values (non-numeric, missing coordinate) are silently ignored | string | — |
overlap | Circular inset: when wrapping circular content (e.g. an avatar), the badge tucks inside the circle edge (the translate amount shrinks from 50% to ~29%, the 1-√2/2 geometric inset); affects corner badge mode only | boolean | — |
placement | Ribbon position: start (inline-start) / end (inline-end, default) | BadgePlacement | end |
premium | Metallic treatment: a multi-stop gold gradient with a deep-gold fine outline (clipped shapes get the outline traced along their clip-path silhouette), text color fixed to near-black #1a1a1a; composes orthogonally with color with the priority premium > color > semantic default; works with every ribbon-form, dark theme adapts automatically (driven by the --oas-preset-gold token) | boolean | — |
ribbon | Ribbon corner mode (boolean, same as mode="ribbon") | boolean | — |
ribbon-anchor | Unified ribbon anchor, with the anchor set adapted per shape semantics: fold (left/right edge centers + four corners, a horizontal band hugs left/right with the vertical position adjustable), diagonal/triangle (four corners), side (left/right edge centers + four corners), banner (top/bottom), seal (all 8 positions), bookmark (four corners + four edge centers); an anchor pins the ribbon to an edge/corner (the fold notch auto-flips on bottom anchors) and offset fine-tunes any arbitrary position; when unset it falls back to the placement / ribbon-position / ribbon-direction / ribbon-vertical aliases, invalid values or unsupported anchor-shape combos silently fall back | BadgeRibbonAnchor | — |
ribbon-direction | Swallow-tail notch direction of bookmark: down (default, hangs from the top edge with the notch downward) / left (tab against the right edge with the notch pointing left) / right (tab against the left edge with the notch pointing right); physical-direction semantics (not flipped in RTL); only takes effect with ribbon-form="bookmark", invalid values silently fall back to down | BadgeRibbonDirection | down |
ribbon-form | Ribbon shape: fold (default, straight band + folded corner) / diagonal (45° diagonal band from the top corner; the band extends outside the card, so the host needs overflow: hidden to clip it) / triangle (a pure corner triangle holding a small icon or slot="ribbon" content) / bookmark (a vertical tab hanging from the top edge with a swallow-tail notch) / side (a vertical strip hung at mid-height of the side edge) / seal (a circular serrated stamp with centered text) / banner (a full-width strip across the top edge with angled ends) / flag (a side swallow-tail banner: a horizontal band with a V notch at the protruding end, always facing the protruding side) / rounded (rounded end) / zigzag (serrated end) / arrow (arrow-point end); the ribbon-position trio only affects fold, the other shapes have their own vertical placement, invalid values silently fall back to fold | BadgeRibbonForm | fold |
ribbon-position | Ribbon vertical position: hang (default, hangs below the top edge) / edge (flush with the top edge) / cross (straddles the top edge, pressing against the card border for the strongest wrap-around feel); orthogonal to placement (start / end), affects the ribbon-form="fold" shape only, invalid values silently fall back to hang | BadgeRibbonPosition | hang |
ribbon-size | Diagonal band size tier: small (default, 30px tall / xs font) / medium (33px / sm font, 35px pin) / large (36px / md font, 45px pin, wide large-type scenes); sm/md/lg are accepted aliases; a tier only changes the fallback of --oas-badge-diagonal-*, host custom properties take precedence; only takes effect with ribbon-form="diagonal", invalid values silently fall back to small | BadgeRibbonSize | small |
ribbon-vertical | Vertical position of the side-mount bookmark forms (ribbon-direction="left" / "right"): center (default, vertically centered) / top (flush with the top edge) / bottom (flush with the bottom edge); only affects the side-mount forms, invalid values silently fall back to center | BadgeRibbonVertical | center |
rolled | End roll: a boolean modifier that rolls the card-inner end (large radius on the inner end + a darkening gradient reading as a rolled cylinder; the outer end sits flush with the card edge and no longer protrudes; pure CSS). Composes with fold / flag / rounded / zigzag / arrow (banner keeps its own angled ends and gets no roll; diagonal / triangle / bookmark / side / seal silently ignore it) | boolean | — |
shape | Badge shape round (default) / square / pill, applying to both counts and dots | string | — |
showZero | Whether to show when value=0 | boolean | — |
size | Size tier: small (compact, numeric badge ~13px tall, dot 6px) / medium (default, ~16px) / large (~20px, dot 10px); invalid values silently fall back to medium | BadgeSize | medium |
status | Status point: success / processing / default / error / warning, renders an inline standalone element of "status dot + text", mutually exclusive with ribbon / dot / count modes (rendered first when set); the processing dot pulses (prefers-reduced-motion disables it) | BadgeStatus | — |
text | Ribbon or status text; the ribbon slot takes precedence when it has content | string | — |
value | Number | string | — |
variant | Variant: solid (default, filled) or outline (transparent background, border and text follow the color semantics); invalid values silently fall back to solid | BadgeVariant | — |
Slots
| Name | Description |
|---|---|
| default | Wrapped content (card, button, etc.); with no content the badge falls back to a standalone inline element |
ribbon | Custom ribbon content |
CSS Variables
| CSS Variable | Description | Default |
|---|---|---|
--oas-badge-bg | — | var(--oas-color-danger) |
--oas-badge-diagonal-font | — | var(--oas-font-size-xs) |
--oas-badge-diagonal-height | — | 30px |
--oas-badge-diagonal-pin | — | 25px |
--oas-badge-diagonal-text-inset | — | 0px |
--oas-badge-on-color | — | var(--oas-color-text-on-danger) |
--oas-badge-outline | Border and text color of the outline variant (the component injects the -text safe variant for semantic/preset color; falls back to the badge background color) | var(--oas-badge-bg, var(--oas-color-danger)) |
--oas-badge-pos | — | translate(50%, -50%) |
--oas-badge-pulse-color | — | var(--oas-badge-bg, var(--oas-color-danger)) |
--oas-diag-pin | — | var(--oas-badge-diagonal-pin, 25px) |
--oas-ribbon-anchor-x | — | 0px |
--oas-ribbon-anchor-y | — | 0px |
--oas-ribbon-offset-x | — | 0px |
--oas-ribbon-offset-y | — | 0px |
--oas-status-color | — | var(--oas-color-text-secondary) |