Ribbon
A corner ribbon: a diagonal banner pinned to a container's corner for a short label, in any tone.
Live demo
Ribbon is the diagonal corner banner for a short call-out on a card, a tile, or an image: New, Beta, Sale, Featured. tone skins it across the six semantic roles (plus the accent variants and named hues), variant picks a solid fill or a soft tint, corner chooses which of the four corners it hugs, and size steps the band from sm to lg.
A color / textColor pair is the escape hatch for a band background and text past the tone set. It fills its container as a clipping overlay, so the band's overhang is trimmed to the container's edges and the ribbon reads as a real folded banner rather than a floating strip; the container just needs position: relative (the ribbon clips itself to the container's box, rounded corners included). It ships as a first-class element that self-styles in its own shadow root, so a shadow-DOM consumer with no global stylesheet gets it for free, and the .xtyle-ribbon utility class stays available for global-CSS pages. Ribbon is decoration, not a control: the overlay is pointer-events: none, and its short label is rendered as visible text, so it reads to assistive tech in the container's reading order. Keep the label short; the band is a fixed width per size and a longer label clips.
When to use
How this component composes with the rest of the set.
Props
7 props, straight from the manifest.
| Prop | Type | Default | Bindings | Description |
|---|---|---|---|---|
solid tone fill or a soft tinted band. | ||||
--rb-bg and wins over tone. Pair it with textColor so the label stays legible on a custom fill. | ||||
color fill (sets --rb-fg). Set both together so a raw-color ribbon keeps its text readable; on a tone it is unneeded. | ||||
New or Sale. |
Appearance
Variants
solid
A solid tone fill with on-tone text (the default).
soft
A soft tinted band with tone-colored text.
accent
accent-toned ribbon.
neutral
neutral-toned ribbon.
danger
danger-toned ribbon.
success
success-toned ribbon.
warn
warn-toned ribbon.
info
info-toned ribbon.
accent-2
accent-2-toned ribbon.
accent-3
accent-3-toned ribbon.
accent-4
accent-4-toned ribbon.
red
red-toned ribbon.
orange
orange-toned ribbon.
yellow
yellow-toned ribbon.
green
green-toned ribbon.
blue
blue-toned ribbon.
purple
purple-toned ribbon.
brown
brown-toned ribbon.
pink
pink-toned ribbon.
cyan
cyan-toned ribbon.
gray
gray-toned ribbon.
white
white-toned ribbon.
black
black-toned ribbon.
Sizes
sm
Compact.
md
Default.
lg
Large.
States
top-right
Pinned to the top-right corner (default).
top-left
Pinned to the top-left corner.
bottom-right
Pinned to the bottom-right corner.
bottom-left
Pinned to the bottom-left corner.
Anatomy
The named parts that make up the component. A ::part() handle is reachable from your own stylesheet; the class beside it is the component's internal selector, which a shadow boundary keeps to itself.
ribbon
The clip layer: an absolutely-positioned overlay that fills the container and trims the band's overhang.
band
The diagonal banner itself: the rotated strip carrying the label, filled with the resolved tone.
Tokens & coverage
What the component consumes, checked live against what the algorithm produces.
Live coverage check against the xtyle-default register
(derive(xtyleDefault, { anchors }) →
coverComponent(manifest, register)). Every token this component
consumes must be a key the algorithm produces.
--accent--accent-2--accent-2-bg--accent-2-fg--accent-2-text--accent-3--accent-3-bg--accent-3-fg--accent-3-text--accent-4--accent-4-bg--accent-4-fg--accent-4-text--accent-bg--accent-fg--accent-text--black--black-bg--black-fg--black-text--blue--blue-bg--blue-fg--blue-text--brown--brown-bg--brown-fg--brown-text--cyan--cyan-bg--cyan-fg--cyan-text--danger--danger-bg--danger-fg--danger-text--elevation-2--gray--gray-bg--gray-fg--gray-text--green--green-bg--green-fg--green-text--info--info-bg--info-fg--info-text--neutral--neutral-bg--neutral-fg--neutral-text--orange--orange-bg--orange-fg--orange-text--pink--pink-bg--pink-fg--pink-text--purple--purple-bg--purple-fg--purple-text--red--red-bg--red-fg--red-text--success--success-bg--success-fg--success-text--text-lg--text-sm--text-xs--warn--warn-bg--warn-fg--warn-text--weight-semibold--white--white-bg--white-fg--white-text--yellow--yellow-bg--yellow-fg--yellow-textAccessibility
Code
Corners, tones, and variants
A ribbon pinned to each corner, in solid and soft fills across the semantic tones.
<div style="position: relative; width: 16rem; height: 9rem; border-radius: var(--radius-lg); background: var(--bg-1);">
<xtyle-ribbon tone="accent" label="New"></xtyle-ribbon>
<!-- …card content… -->
</div>
<div style="position: relative; …">
<xtyle-ribbon tone="danger" corner="top-left" label="Sale"></xtyle-ribbon>
</div>
<div style="position: relative; …">
<xtyle-ribbon tone="success" variant="soft" corner="bottom-right" label="Beta"></xtyle-ribbon>
</div><script lang="ts">
import { Ribbon } from "@xtyle/svelte";
</script>
<!-- the container only needs position: relative; the ribbon clips itself -->
<div style="position: relative;">
<Ribbon tone="accent" label="New" />
<!-- …card content… -->
</div>
<div style="position: relative;">
<Ribbon tone="danger" corner="top-left" label="Sale" />
</div>
<div style="position: relative;">
<Ribbon tone="success" variant="soft" corner="bottom-right" label="Beta" />
</div>---
import Ribbon from "@xtyle/astro/Ribbon.astro";
---
<!-- the container only needs position: relative; the ribbon clips itself -->
<div style="position: relative;">
<Ribbon tone="accent" label="New" />
<!-- …card content… -->
</div>
<div style="position: relative;">
<Ribbon tone="danger" corner="top-left" label="Sale" />
</div>
<div style="position: relative;">
<Ribbon tone="success" variant="soft" corner="bottom-right" label="Beta" />
</div>