Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Backgrounds

Pro

Underwater Background for React

A view through sunlit water: light shafts sway down from the surface while tiny motes rise through the blue. For React with Base UI, when a meditation, spa or ocean page should feel calm and submerged.

Framework

A view through sunlit water: shafts of light sway down from the surface, soft patches of light drift above, and tiny motes rise slowly through the blue with a gentle side-to-side sway. It's CSS gradients and keyframes with no blur filter and no script; the motes are placed by a fixed seed, so every render matches, and each moves with a single animation the browser composites without repainting.

Use it behind a meditation or spa page, a marine conservation hero or an ocean-themed landing page. For the bright net of light on a pool floor, use Caustics; for darker water with glowing creatures, Deep Sea; for larger rising circles, Bubbles; for the open sea out to the horizon, Ocean.

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 { Underwater } from "@/components/ui/underwater";
<Underwater className="flex min-h-[420px] items-center justify-center">
  <h1 className="text-5xl font-semibold">Slow down, breathe out</h1>
</Underwater>

Underwater is a container: whatever you put inside sits on top of the water, in normal flow. It paints its own water, so give it a height or content. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10". The water follows the colour scheme: sunlit shallows on a light page, deep water on a dark one, both made from the same waterColor.

Demos

Calm

A quieter card: count={20} halves the motes, speed={0.5} slows everything down and intensity="subtle" dims the light, so the water reads deeper.

Preview width

Kelp

waterColor and lightColor take any CSS colours: here a green sea under pale yellow light. The water is still lifted toward the light on a light page and deepened on a dark one.

Preview width

Accessibility

The water is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion everything stops where it is: the shafts hold their angle and the motes stay scattered through the water, so a still picture remains. Nothing flashes: the shafts brighten and dim over 8 to 13 seconds.

Put copy in your foreground colour (text-foreground). It keeps at least 4.4:1 at the brightest moment behind a headline and 5.4:1 behind body text, in both colour schemes. On a dark page the light is strongest near the top, so keep small text out of the top fifth, or use intensity="subtle".

FAQ

What makes the light shafts?

Gradient strips that fade down their length, with soft masked sides instead of a blur. Each hangs from the top at its own tilt, sways a few degrees and brightens and dims on its own slow rhythm.

What are the floating specks?

Motes, like plankton or dust in the water: count of them (40 by default, up to 120), 1 to 3 pixels wide, each rising through the whole box in 12 to 25 seconds while it sways from side to side. Their places come from a fixed seed, so they're the same on every render.

Can I change the water colour?

Yes. waterColor tints the water, lighter on a light page and deeper on a dark one, and lightColor colours the shafts, patches and motes. You can also set --underwater-water and --underwater-light in your CSS.

How do I make it feel deeper or shallower?

intensity sets how strong the light is: subtle reads deeper, strong like sunlit shallows. Fewer motes and a lower speed make it calmer.

Is there a canvas?

No. It's CSS animations of transform and opacity, one per mote and shaft, which the browser composites without repainting. There's no script, so it renders the same on the server.

What happens with reduced motion?

Everything stops where it is: the shafts at their angle, the motes scattered through the water, so the scene stays as a still picture.

API Reference

Underwater

<div> data-slot="underwater"

PropType
count?number

How many motes drift up through the water, from 0 to 120. @default 40.

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

How strong the light is: subtle reads deeper, strong like sunlit shallows.

Type
"subtle" | "medium" | "strong"
Default
"medium"
lightColor?string

The light's colour, any CSS colour: the shafts, patches and motes.

speed?number

How fast everything moves: 2 is twice as fast, 0.5 half as fast.

Default
1
waterColor?string

The water's colour, any CSS colour. It's lightened into sunlit shallows on a light page and deepened on a dark one.

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
--underwater-alphastring
--underwater-lightstring

The light's colour (a pale aqua).

--underwater-sizestring
--underwater-speedstring

The motion's speed, a multiplier (1).

--underwater-tiltstring
--underwater-waterstring

The water's colour (a sea blue).

--underwater-widthstring
--underwater-xstring
All 100 backgrounds