Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Plasma Background for React

A demoscene plasma tuned to sit behind content: soft bands of colour sweep across a box, ring around hot spots and slowly shift through the palette. For React with Base UI, when a music, hackathon or launch page wants flowing colour with a retro soul behind its copy.

Framework

A demoscene plasma, tuned to sit behind content: soft bands of colour sweep across the section, ring around hot spots and slowly shift through the palette, pastel sky, lavender, rose and peach on a light page and deep indigo, violet, magenta and amber on a dark one. Four soft grey waves slide past each other in CSS, a white veil fades in and out over them, and an SVG gradient map turns their mix into colour, the demoscene's lookup table done by the browser, with no canvas and no script. The bands run through the palette and back, so each colour only ever meets its neighbours and nothing turns muddy.

Use it behind a music app's hero, a hackathon splash or a retro launch page. For one smooth sweep of colour without bands, use Silk; for the same gradient map with a thermal palette and drifting hot spots, Heatmap; for an iridescent foil sheen, Hologram.

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 { Plasma } from "@/components/ui/plasma";
<Plasma className="flex min-h-[32rem] items-center justify-center">
  <h1 className="text-5xl font-semibold">Turn up the signal</h1>
</Plasma>

Plasma is a container: whatever you put inside sits on top of the colour, in normal flow. It fills its own box, so give it a height or content. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10".

Demos

Subtle

intensity="subtle" lays more of your page's background over the plasma, so body text and buttons read easily on it; scale={1.5} packs the bands tighter, which suits a smaller box.

Preview width

Colors

colors takes 3 to 8 hex colours, used in both colour schemes; here the demoscene original, magenta, purple, cyan, yellow and lime, at full strength (intensity="strong"), with shift={0.6} sliding the palette further and speed={1.5} moving faster. At full strength it's loud and the same in both colour schemes, so put copy on a card.

Preview width

Accessibility

The plasma is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion the waves and the palette hold still, and a still plasma stays. Nothing flashes: the palette slides once every 16 seconds and back.

Put copy over it in your foreground colour (text-foreground). With the default palettes, the default medium keeps it above 8:1 in light mode and above 5:1 in dark mode at the worst moment, and subtle higher still. At strong your page's background no longer softens it, and with your own colors it depends on them: check the contrast, and keep copy on a surface over a loud palette.

FAQ

How is it made without a canvas?

Grey sine waves slide past each other in CSS, each moved by translate, which the browser composites without repainting. An SVG feComponentTransfer filter then looks up each pixel's brightness in the palette, the demoscene lookup table done by the graphics card.

How do I change the palette?

Pass 3 to 8 hex colors; they replace both default palettes. They have to be hex, because an SVG filter can't read CSS variables. The bands run through them and back, so put neighbours next to each other (cool to warm, say) for the smoothest bands.

Why does it look different in dark mode?

It has two palettes: a light, low-chroma one for a light page and a deep one for a dark page, picked by the colour scheme. A darkened light palette turns muddy, so dark mode gets its own.

What does shift do?

It slides every colour along the palette and back, so colour flows through the bands; 0 holds the palette still, 1 slides it furthest.

It's too loud behind my text.

Use intensity="subtle": more of your page's background is laid over the plasma. scale changes how tight the bands are.

Is it heavy?

No script runs. Five layers slide or fade on the compositor, and the gradient map runs once per frame on the graphics card, a cheap per-pixel lookup with no blur. It pauses offscreen.

Does it respect reduced motion?

Yes. The waves stop and the palette holds, so a still plasma stays on screen.

API Reference

Plasma

<div> data-slot="plasma"

PropType
colors?string[]

The palette, 3 to 8 hex colours (#ec4899 or #e49), used in both colour schemes. It must be hex: an SVG filter maps brightness to these colours, and SVG filters can't read CSS variables. The bands run through it and back, so neighbours blend and there's no seam. By default a pastel sky, lavender, rose and peach in light mode and a deep indigo, violet, magenta and amber in dark mode.

intensity?"subtle" | "medium" | "strong"

How much of your page's background is laid over the plasma: strong none, medium a little, subtle the most, for text-heavy sections.

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

How tight the bands are: 2 packs twice as many into the box, 0.5 half as many.

Default
1
shift?number

How far the palette slides along and back, from 0 (it holds) to 1.

Default
0.3
speed?number

How fast the waves move: 2 is twice as fast, 0.5 half as fast.

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
--plasma-mapstring
--plasma-map-darkstring
--plasma-scalestring

How tight the bands are, a multiplier (1).

--plasma-shiftstring

How far the palette slides, 0 to 1 (0.3).

--plasma-speedstring

How fast the waves move, a multiplier (1).

All 100 backgrounds