Backgrounds

Silk Ribbons Background

A silk ribbon background drawn with Canvas 2D: several bezier ribbons sway slowly over a dark ground, with gradients across their width simulating a glossy sheen; no WebGL.

This is a WebberUI Pro component

The install command below needs a licence to run; without one it returns 401.

How to install Pro components →See the plans →

A background for launch headers, campaign key visuals and brand sections: 3–6 silk ribbons sway slowly over a dark ground, each shaded across its width with a gradient that reads as satin — dark edges, a highlight off to one side, the base color in the middle — and the highlight brightens where a ribbon twists and narrows. Ribbons are combined with screen blending, so overlaps glow naturally. Everything is drawn with Canvas 2D; no WebGL.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add "https://webberui.com/r/silk-ribbons-background.en.json?t=<install token>"

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

4
1
0.7
7
Active edited usageDefault props
<SilkRibbonsBackground/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add "https://webberui.com/r/silk-ribbons-background.en.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/silk-ribbons-background.

Usage

import { SilkRibbonsBackground } from "@/components/ui/silk-ribbons-background";

<SilkRibbonsBackground
  count={4}
  color={["#1e3a8a", "#4f46e5", "#0ea5e9", "#8b5cf6"]}
  className="flex h-[420px] items-center justify-center"
>
  <h1 className="text-4xl font-bold text-white">Make every launch feel crafted</h1>
</SilkRibbonsBackground>

Pass a single color and neighboring shades are derived automatically:

<SilkRibbonsBackground color="#e11d48" background="#1a0509" className="h-[360px]" />

Override the pace and ground color site-wide with CSS variables:

:root {
  --wb-silk-speed: 0.6; /* multiplied with the speed prop */
  --wb-silk-bg: #05060a; /* ground color when no background is passed */
}

Props

PropTypeDefaultDescription
countnumber4Number of ribbons, clamped to 3–6
speednumber1Flow speed multiplier, further multiplied by --wb-silk-speed
colorstring | string[]['#3b82f6','#6366f1','#0ea5e9','#8b5cf6']A single color derives neighboring shades; an array gives one color per ribbon, cycled
sheennumber0.7Sheen strength (0–1), the brightness of the white highlight
seednumber7Random seed that sets ribbon positions, widths and sway rhythm
backgroundstringvar(--wb-silk-bg, #05060a)Container background color
childrenReactNode—Foreground content layered above the ribbons
canvasClassNamestring—Class applied to the canvas
classNamestring—Container styling (layout, height, corner radius, and so on)

How it works

  • Each ribbon's centerline is a Catmull-Rom curve through 6 control points whose y positions sway with two summed sin waves at different frequencies, for a full cycle of roughly 12–20 seconds. Every parameter is derived deterministically from seed, so the same seed always draws the same picture.
  • 120 samples are taken along the centerline and expanded along the normal into segment quads, each filled with a linear gradient across the width: the edges at 20% of the base color's brightness, a white highlight at 0.35 (strength 0.5 × sheen), and the base color in the middle. Width varies by cos along the length for a twisting feel, and the highlight strengthens where the ribbon narrows.
  • Each ribbon is drawn to an offscreen layer and then screened onto the main canvas, so overlaps glow without bright seams at segment joins; a very faint radial vignette goes on last.
  • The canvas scales with devicePixelRatio (capped at 2x) and ResizeObserver recomputes on resize; requestAnimationFrame stops when the canvas scrolls out of view (IntersectionObserver) or the tab is hidden.
  • The first render outputs only the container with its background color; the canvas is drawn in an effect, so SSR and the client match.

Accessibility

  • The canvas has aria-hidden, role="presentation" and pointer-events-none: purely decorative, it never interferes with clicks or screen readers, and children read normally.
  • The default ground is dark and foreground text defaults to text-neutral-50; if you switch to a light background, adjust the text color to keep contrast.
  • When the user has "reduce motion" enabled in system settings, a single still frame is drawn (its moment in time set by seed) and the animation loop never starts.