Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Ribbons Background for React

Long silk ribbons that sweep diagonally across a box, twisting as they flow and catching the light. For React with Base UI, when a launch page or a keynote-style hero needs a moment of color and motion.

Framework

Long silk ribbons sweep diagonally across the box, from one edge to another, and twist as they flow: each narrows to an edge where it turns, catches a highlight just before, falls into shade just after, and shades from one color into the next along its length. The farthest ones are larger, softer and slower, so the scene has depth, and on a dark page the ribbons glow and add their light where they cross. Each ribbon's outline is drawn once, a seeded shape the install adds to your stylesheet, and its colors and light are CSS gradients; CSS slides each one along its own length and sways it, so nothing is redrawn while they move, and no script runs.

Use it for launch pages, product announcements and keynote-style heroes. For a soft satin surface instead of separate ribbons, use Silk; for curtains of light, Aurora; for blurred bands of color that run straight across, Wavy; for quiet filled waves, Light Waves.

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Usage

import { Ribbons } from "@/components/ui/ribbons";
<Ribbons className="flex min-h-[480px] items-center justify-center">
  <h1 className="text-5xl font-bold">Launch week</h1>
</Ribbons>

Ribbons is a container: give it a size, put your content inside, and the ribbons sit behind it. They show over the page's background, or over one you give the root with a class. The ribbons scale with the box, so they cross a portrait card as well as a wide banner. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10".

Demos

Keynote

A deep indigo stage, set with a class on the root, with text-white for copy on top. The root also has the dark class, so the ribbons glow and add their light where they cross even when the page is in light mode.

Preview width

Color

colors takes up to four CSS colors and cycles them over the ribbons, each shading into the next; here the theme's chart colors. count={3} with thickness={1.4} gives three wide ribbons, and speed={0.6} slows them down.

Preview width

Accessibility

The ribbons are decoration: they're hidden from assistive tech and never take the pointer. With reduced motion they stop where they are, and the composition stays. Nothing flashes: the highlights move only as fast as the ribbons flow.

Put copy over them in your foreground color (text-foreground). At the default intensity it keeps about 5:1 on a light page and 4.5:1 on a dark one over the content area at the worst frame; on a dark page a highlight can briefly dip a few spots toward 3.4:1, so give small text some weight or keep it off the brightest crossings. intensity="subtle" calms them further behind body text.

FAQ

How many ribbons should I use?

count, from 1 to 6, 5 by default. They share the diagonal evenly, so two or three make a calm hero with a bold headline and six a dense, theatrical one.

Can I change the colors?

Yes. colors takes up to four CSS colors and cycles them over the ribbons; each ribbon shades from its color into the next along its length. The default is violet, rose, sky and indigo. You can also set --ribbons-color-1 to --ribbons-color-4 in your CSS.

How do I make the ribbons wider or thinner?

thickness is a multiplier from 0.5 to 2, 1 by default: it widens the ribbons and deepens their waves together. The ribbons already scale with the box, so you rarely need it for a small card.

How do the ribbons twist without a canvas?

Each ribbon's outline is a seeded shape whose width follows the cosine of its twist, so it narrows to nothing where it turns edge-on, and a gradient along its length puts the highlight and shade where a real ribbon would catch the light. Both are drawn once; only the ribbon's wrapper moves.

Why do the crossings glow only in dark mode?

In dark mode the ribbons add their light together (mix-blend-mode: plus-lighter), so crossings brighten. On a light page adding light would wash them out, so they're translucent tints there, with the shade doing more of the work. Put dark on the root, as in the keynote demo, for the glow on a dark stage in a light page.

How do I slow the motion down?

speed divides every duration: 0.5 is half as fast, 2 twice as fast. At 1 each ribbon flows one period along its length in 46 to 86 seconds and sways in 13 to 21, so they never move in step.

Will it slow my page down?

No. Each ribbon is one layer that moves with translate and transform, which the browser composites without repainting; the outlines, gradients and halos are drawn once. There's no JavaScript.

API Reference

Ribbons

<div> data-slot="ribbons"

PropType
colors?string[]

Up to four CSS colours, cycled over the ribbons; each ribbon shades from its colour into the next along its length. By default violet, rose, sky and indigo.

count?number

How many ribbons, from 1 to 6. @default 5.

Default
5
intensity?"subtle" | "medium" | "strong"

How strongly the ribbons show: subtle behind body text, strong for an empty hero.

Type
"subtle" | "medium" | "strong"
Default
"medium"
speed?number

How fast the ribbons flow and sway: 2 is twice as fast, 0.5 half as fast.

Default
1
thickness?number

How wide the ribbons are and how far they wave, a multiplier from 0.5 to 2.

Default
1
render?ReactElement | ((props: object, state: object) => ReactElement)

Replace the host element or compose it with another component.

Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string

Merged with the part's classes.

CSS variableType
--ribbons-color-1string

The first colour (violet); --ribbons-color-2 to -4 the others.

--ribbons-speedstring

How fast the ribbons flow and sway, a multiplier (1).

--ribbons-thicknessstring

How wide the ribbons are, a multiplier (1).

All 100 backgrounds