Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Wave Grid Background for React

A wireframe surface seen from above, its rows and columns rising and falling as waves cross it. For React with Base UI, when a tech, data or AI product page wants a cutting-edge 3D surface under its headline.

Framework

A wireframe surface seen from above: rows of a grid recede toward a horizon, packed tighter in the distance, and rise and fall as crossing waves pass through them. A small canvas redraws the grid each frame from three sine waves, one path per row from the back to the front, with nearer rows brighter; a mask fades the far rows and the sides into your page. It runs only while it's on screen, with no animation library.

Use it under a hero's headline on a tech, data or AI product page. For a flat perspective grid that scrolls, use Retro Grid; for contour lines of a moving surface, Topography; for the same sea in colour, Ocean; for a static grid, Grid Pattern.

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 { WaveGrid } from "@/components/ui/wave-grid";
<WaveGrid className="flex min-h-[460px] flex-col items-center pt-16">
  <h1 className="text-5xl font-semibold">Signal from the surface</h1>
</WaveGrid>

Wave Grid is a container: whatever you put inside sits on top, in normal flow. The surface fills the lower half of the box, under a horizon at 42% of its height, so put copy above it. There's no painted panel: your page's background shows through, and the lines take your theme's primary colour. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10".

Demos

Cyan

shadcn.io's original look: color="#06b6d4" on a near-black panel (bg-[#030712]). interactive makes the surface swell up under the pointer and settle when it leaves.

Preview width

Dense

cellSize={24} packs the grid tighter and intensity="subtle" halves the waves' height, here in a small card.

Preview width

Accessibility

The canvas is decoration: it's hidden from assistive tech and never takes the pointer, so your content is read and clicked as usual. With reduced motion it draws the surface once, still, and ignores the pointer. Nothing flashes. The surface stays in the lower half of the box, faded at the top and sides, so copy above it keeps your foreground colour's full contrast with the page.

FAQ

How is the 3D effect made?

Each grid point's height comes from three sine waves crossing at different angles and speeds. The point is then projected from a camera above the grid: rows further back are drawn closer together, smaller and fainter, toward a horizon at 42% of the box's height.

What moves?

The waves' phases advance with time; the grid itself stays put, so the surface ripples in place. speed sets the pace: 0.5 is a slow swell, 2 a choppy sea.

Can I change the colour?

Yes. color takes any CSS colour; by default it's your theme's --primary, so the grid is dark on a light page and light on a dark one. You can also set --wave-grid-color in your CSS.

How do I make it denser or calmer?

cellSize sets the grid's spacing in pixels (40 by default, at least 16), and intensity the waves' height: subtle, medium or strong.

Does it react to the pointer?

Only with interactive: the surface swells up in a soft hill under the pointer and settles when it leaves. Touch never does it, so scrolling a page on a phone isn't disturbed.

Does it cost much?

About 0.15 milliseconds of script a frame for a full-width hero. The loop stops when the background scrolls out of view and the browser pauses it in a hidden tab; with reduced motion it draws once and never loops.

API Reference

WaveGrid

<div> data-slot="wave-grid"

PropType
cellSize?number

The grid's spacing, in pixels, at least 16: smaller is denser. @default 40.

Default
40
color?string

The lines' colour, any CSS colour. @default "var(--primary)".

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

How tall the waves are. @default "medium".

Type
"subtle" | "medium" | "strong"
Default
"medium"
interactive?boolean

Whether the surface swells up under the pointer. @default false.

Default
false
speed?number

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

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
--wave-grid-colorstring

The lines' colour (the theme's --primary).

All 100 backgrounds