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 |
|---|---|---|---|---|
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, with their selectors.
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-text
Accessibility
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>