The animated gradient every landing page reaches for — done properly. Instead of the usual 400% background-size hack that scrubs a static gradient sideways, this registers the angle and the colour stops themselves as typed custom properties with @property, so the browser interpolates real colour and real rotation on the compositor. Four palettes and three speeds are wired with radio chips and :has() — zero JavaScript, and the reader can feel each value before copying it.
Published
02 / 25Light JSNEW
Cursor Spotlight Follow Effect
A torch dragged across a dark surface. Two lines of pointer JavaScript write --mx / --my; everything else — the light falloff, the mask that reveals a hidden colour layer underneath, the grid that brightens only inside the beam — is CSS. It idles on its own orbit until you move, so it is never a dead rectangle on touch devices, and it hard-stops for reduced-motion users.
Published
03 / 25Pure CSSNEW
Animated Dot Grid Pattern
The dotted canvas that every modern dev-tool site now uses as its default surface — but with depth. Three tiled radial-gradient layers scroll at different speeds and different dot sizes for real parallax, a radial mask fades the field into the page edges, and a slow luminance wave crosses the grid so the dots twinkle in a band rather than all at once. Density, dot size and drift are switchable in-page.
Published
04 / 25Pure CSSNEW
Grain & Noise Texture Overlay
The texture that makes a flat gradient look printed instead of rendered. An inline SVG feTurbulence filter generates real fractal noise as a data URI — no PNG request, no 200KB tiling image — and a steps() animation jitters it eight times a second for authentic film grain rather than a frozen static layer. Three intensities and three blend modes are switchable so you can dial it against your own art direction.
Published
05 / 25Pure CSSNEW
Topographic Contour Line Flow
Elevation lines that slowly reshape themselves, like a survey map redrawing itself. A stack of hard-stop repeating-radial-gradient rings is pushed through an SVG feDisplacementMap driven by fractal turbulence — the rings stop being circles and become a landscape. SMIL animates the noise seed inside the SVG, so the terrain flows continuously with no JavaScript at all.
Published
06 / 25Pure CSSNEW
Diagonal Moving Stripes Pattern
The barber-pole stripe, engineered instead of hacked. Because the stripe angle is a registered <angle> property it can be animated, not just set — so the pattern can rotate mid-loop, something the classic repeating-linear-gradient(45deg,…) approach can never do. Two counter-moving stripe layers with a soft-light blend create the moiré depth, and stripe width, pitch and speed are all live controls.
Published
07 / 25Pure CSSNEW
Animated SVG Wave Layers
Four wave bands sliding across each other at different speeds and amplitudes — the layered-ocean hero, built the way it should be. Each wave is one seamlessly tiling SVG path duplicated end to end inside a 200%-wide layer, translated by exactly 50%, so the loop is mathematically invisible. Layers also bob vertically on a longer, coprime period, which is what stops the parallax from ever repeating a composition.
Published
08 / 25Pure CSSNEW
Plasma / Lava Lamp Fluid Effect
Metaballs with no maths, no canvas and no WebGL. The gooey filter — blur() followed by a hard contrast() — turns overlapping blurred circles into a single fused fluid that stretches and snaps apart exactly like a real lava lamp. Six blobs on coprime orbits do the rest, and a screen-blended plasma layer underneath supplies the colour heat.
Published
09 / 25Pure CSSNEW
Animated Bokeh Light Blur
Out-of-focus lights drifting through a dark frame, with real optical logic: the nearer a light is, the larger, blurrier and faster it moves, and the more it overexposes to white in the centre. That single rule — size, blur, speed and core brightness all keyed to one depth token — is what separates convincing bokeh from a pile of blurred circles.
Published
10 / 25Light JSNEW
Particle Constellation Network
The connected-dots network, rewritten as forty lines of dependency-free Canvas 2D instead of a 60KB library. Particles drift, link to neighbours within a radius, and pull toward the cursor; density scales to the viewport area, the loop is DPR-correct, and it stops itself entirely when the section scrolls out of view or the user asks for reduced motion.
Published
11 / 25Light JSNEW
Starfield Warp Speed Transition
A real perspective starfield — stars live in 3D and are projected to the screen, so they streak outward with correct parallax instead of sliding on a flat plane. Press Engage and the warp factor eases from 1 to 22 over a second and a half, stretching every star into a light trail: the classic hyperspace page transition, in about fifty lines with no library.
Published
12 / 25Pure CSSNEW
CRT Scanline Overlay Background
A CRT that actually behaves like one: an aperture-grille RGB triad at sub-pixel scale, horizontal scanlines at a different pitch, a rolling refresh bar that drifts down the tube, phosphor bloom, barrel-vignette curvature, and a chromatic-aberration text shadow. Every layer is a gradient — no images, no canvas, no JavaScript.
Published
13 / 25Pure CSSNEW
Animated Fog / Mist Drift Background
Three sheets of fractal-noise fog crossing the frame at different heights, speeds and directions, so the density in front of you is always changing. The noise is generated by an inline SVG filter — one data URI, no cloud PNGs — and each sheet is masked into a horizontal band, which is why it reads as ground mist instead of a texture laid over the whole screen.
Published
14 / 25Pure CSS
Animated Mesh Gradient Background
The soft multi-colour wash that every modern SaaS front page now runs behind its hero — built as five independently orbiting radial gradients rather than one baked image, so it moves, retheming is a five-token edit, and it costs one paint layer instead of a 400KB JPEG. Because the stops are registered <color> properties, the palette itself can cross-fade while the shapes drift.
PublishedUpdated
15 / 25Pure CSS
Aurora Borealis Glow Background
Northern lights as light curtains, not blurred blobs. Each ribbon is a tall conic-gradient sheet, skewed, masked into a vertical falloff and blended with screen, so where two ribbons cross the colour genuinely adds — the way emission spectra do. They breathe on coprime periods above a starfield and a snow-lit horizon.
PublishedUpdated
16 / 25Light JS
Interactive Water Ripple Background
Touch the surface and it answers. Each pointer press spawns a self-destructing ripple element — three expanding rings with staggered delays and a refraction wobble — over a caustics layer built from animated turbulence. The JavaScript is nine lines and removes its own DOM nodes on animationend, so an hour of clicking leaves the node count exactly where it started.
PublishedUpdated
17 / 25Pure CSS
Animated Halftone Dot Pattern
Real halftone: dot size carries the tone, exactly as it does on a printing plate. A radial-gradient dot grid is masked by a moving luminance ramp, so dots grow toward the dark end and shrink to nothing in the highlights — and because the ramp animates, the tonal wave sweeps across the plate like a press sheet being pulled. Two colour separations at different screen angles complete the CMYK illusion.
PublishedUpdated
18 / 25Pure CSS
Morphing Organic Blob Animation
Two morphing techniques side by side, because they solve different problems. The big shapes use the eight-value border-radius trick — cheap, GPU-friendly, infinitely loopable. The precise foreground shape uses SVG <animate> path morphing, which can hit exact silhouettes the radius trick can never make. Both run without a line of JavaScript.
PublishedUpdated
19 / 25Pure CSS
Floating Glassmorphism Orbs
Glass spheres, not frosted circles. Each orb layers four things a real glass ball has — a backdrop-filter refraction, an inner rim light from a conic gradient, a specular highlight offset toward the light source, and a contact shadow — and they drift on a slow 3D path so the refraction under them visibly changes. This is the glassmorphism that still looks current, because it is doing optics rather than applying a blur.
PublishedUpdated
20 / 25Light JS
Matrix Digital Rain Effect
Digital rain done right: a bright leading glyph, a decaying trail behind it, per-column speeds, occasional glyph mutation mid-fall, and a frame budget that holds at 4K. It runs at a deliberate 24fps — the film frame rate the effect is remembered from — which also cuts its CPU cost by more than half compared to a 60fps loop nobody can perceive as smoother.
PublishedUpdated
21 / 25Pure CSS
Synthwave 3D Retro Grid
The outrun horizon: a real 3D floor built with perspective and rotateX, scrolling toward you forever, under a slit-scanned neon sun and a chrome horizon glow. The infinite scroll is a single trick — translate the grid by exactly one cell in Z-space — and because the plane is genuinely rotated in 3D, the perspective convergence is correct rather than faked with a skew.
PublishedUpdated
22 / 25Pure CSS
Starry Night Sky & Falling Starfall
Hundreds of stars and a meteor shower, with four DOM nodes. The field is three tiled radial-gradient layers at different densities and parallax speeds, twinkling by opacity; the meteors are five elements with a bright head, a tapered tail drawn by a gradient, and staggered delays on a long cycle so they arrive irregularly — never in a metronomic loop.
PublishedUpdated
23 / 25Pure CSS
Floating Geometric Shapes
Triangles, hexagons, crosses and rings drifting through three depth planes, each plane with its own speed, blur and opacity — so the composition has actual foreground and background rather than being a flat scatter. Every shape is one element with a clip-path, and each one rotates on its own axis while its plane translates, which is what keeps the motion from looking like a single sliding sheet.
PublishedUpdated
24 / 25Pure CSS
Floating Bubble Background
Soap bubbles, not circles. Each one gets an iridescent conic film, a bright specular kiss at the upper left, a thin refractive rim, and a wobble that deforms it slightly as it rises — because a real bubble is a flexible membrane, not a rigid ball. Sizes, speeds and horizontal sway all derive from one inline value per bubble.
PublishedUpdated
25 / 25Pure CSS
Falling Snow / Weather Effect
A three-depth snowfall with real wind — and a pure-CSS weather switch that turns it into rain or a blizzard without a line of JavaScript. Flakes are tiled gradient layers, not hundreds of elements, so a dense storm costs three paint layers; a handful of larger foreground flakes are real elements that tumble as they fall.
PublishedUpdated
FAQ
Frequently asked questions
How do I add an animated background without hurting page performance?
This is the question that matters most for backgrounds, because unlike a card hover or a scroll reveal, a background animates continuously for as long as the page is open. Three rules keep it free. First, animate compositor-only properties — transform (or the modern translate / scale / rotate longhands), opacity, filter, and registered custom properties. Never animate width, height, top or left; those force layout on every frame, and on a full-viewport element that is the difference between free and janky. Every demo here follows that rule. Second, be careful with background-position on very large elements: it is paint work rather than layout, and it is fine on a gradient but expensive over a large bitmap — prefer transforming an oversized pseudo-element instead. Third, keep filter: blur() radii modest and the blurred elements few; blur is the single most expensive effect in this collection and it is what separates a smooth aurora from a hot laptop. Cumulative Layout Shift is inherently zero for all 25 because a fixed or absolutely positioned background reserves no layout space, and none of these affect Largest Contentful Paint since they paint behind real content.
Do these backgrounds work behind text without hurting readability?
Only if you treat contrast as part of the design rather than an afterthought, which is the most common failure with animated backgrounds. Three practical guards. Put a scrim between the background and the text — a semi-opaque overlay or a linear-gradient fade — and check contrast against the brightest frame of the animation, not the resting state. WCAG 1.4.3 requires 4.5:1 for body text and 3:1 for large text, and an animation that passes at frame 0 can fail at frame 60. Second, keep the motion slow and low-amplitude behind reading content; a background that moves quickly under a paragraph makes the text feel unstable even when contrast passes. The demos here that are designed to sit behind copy — gradient shift, mesh, aurora, fog, noise — use long durations and gentle easing for exactly this reason, while the higher-energy ones (starfield, matrix rain, synthwave grid) are built as hero or standalone backdrops. Third, respect prefers-reduced-motion: all 25 stop animating under that query and settle to a static state that still looks intentional, rather than disappearing.
How do I create a grain or noise texture overlay in pure CSS?
The trick is generating the noise with SVG rather than shipping a PNG. An inline SVG filter using feTurbulence produces procedural fractal noise at any resolution, and you reference it as a data URI background: background-image: url("data:image/svg+xml,...feTurbulence baseFrequency='0.8' numOctaves='4'..."). That is typically under 300 bytes versus 50-200KB for a tileable noise image, and it never looks soft on a high-DPI screen. Two parameters do the work: baseFrequency controls grain size (higher is finer, roughly 0.6-0.9 for film grain), and numOctaves controls how detailed the pattern is — 3 or 4 is plenty, and higher values cost render time for no visible gain. Layer it with opacity around 0.03-0.08 and often mix-blend-mode: overlay or soft-light so it modulates the layer beneath rather than sitting on top as grey speckle. To animate it, do NOT animate the filter's own attributes — that re-renders the whole filter every frame. Instead give the noise layer a slight scale and translate the element, or step a background-position between a few fixed offsets, so the grain shimmers without recomputing turbulence. Demos 04 and 13 use this technique.
When should I use canvas instead of pure CSS for a background?
The dividing line is whether elements need to know about each other. CSS handles anything where each moving piece is independent — floating shapes, bubbles, snow, orbs, gradient drift, patterns — because each one is just an element with its own animation and delay. That covers 20 of the 25 demos here, and it is genuinely the better choice: no main-thread work, no JavaScript to hydrate, and the animation keeps running smoothly even while your app is busy. Canvas earns its place when the count is high or the elements interact. The particle constellation network needs to measure the distance between every pair of particles and draw a line when they are close, which is O(n²) relationship logic that CSS has no way to express. Starfield warp speed needs per-particle 3D projection with a shifting focal length. Matrix digital rain needs hundreds of independent character columns with per-frame glyph changes — doable with hundreds of DOM nodes, but far heavier than one canvas. Those three are the canvas demos here, each around 70-90 lines of dependency-free vanilla JavaScript with a requestAnimationFrame loop that pauses when the element scrolls out of view. If you only need drifting dots with no connecting lines, use the CSS version and skip the script entirely.
How do I make a background animation that respects reduced motion?
A continuously animating background is exactly the kind of content that triggers vestibular discomfort, so this is not optional polish. Wrap the motion in @media (prefers-reduced-motion: reduce) and set animation: none — but the important part is what the element looks like afterwards. A background that simply stops can land on an arbitrary frame or, worse, disappear entirely if its resting state was opacity: 0. Every demo here settles to a deliberate static composition: the gradient holds a chosen colour stop, the aurora keeps its glow without drifting, the starfield shows a still field of stars, the snow simply stops falling. The user gets the aesthetic without the movement. For the canvas demos the equivalent is checking the preference in JavaScript — window.matchMedia('(prefers-reduced-motion: reduce)').matches — and drawing a single frame instead of starting the animation loop, which also saves the battery cost of a permanent rAF loop. Worth knowing: roughly one in three adults reports some motion sensitivity, and full-viewport movement is the most provocative kind, so this guard has a larger real-world audience than most accessibility features.
Which background animation fits which kind of site?
Match the energy of the background to the intent of the page, because a background that fights the content costs you conversions rather than winning them. For SaaS and B2B marketing heroes, the low-key options work best — mesh gradient, aurora glow, full-screen gradient shift, dot grid — which is why Stripe, Linear and Vercel all ship variations of exactly these. For developer tools and documentation, the dot grid and topographic contour patterns read as technical without competing with code samples. Agency and portfolio sites can afford more personality: cursor spotlight, morphing blobs, plasma, bokeh. Gaming, esports and Web3 pages are where the high-energy backgrounds belong — synthwave 3D grid, starfield warp, matrix rain, CRT scanlines — and those audiences expect it. Seasonal e-commerce gets falling snow for holiday campaigns, rising bubbles for beverage and clean-tech. Editorial and lo-fi branding suit grain and noise overlays, which add texture without motion drawing the eye. One rule across all of them: the further down the page and the closer to body copy, the calmer the background should be. Save the strongest effect for the hero, where there is no paragraph to read underneath it.
Are these backgrounds responsive, and how do they behave on mobile?
All 25 are built to fill their container at any viewport, using width: 100% with min-height: 100vh plus the 100svh fallback so mobile browser chrome does not clip them. But responsiveness for a background is as much about cost as layout. Blur and large gradients are disproportionately expensive on low-end phones, so the pragmatic pattern — and one worth applying in your own project — is to reduce work below a breakpoint: fewer particles, smaller blur radius, or a static gradient in place of the animation. A media query that swaps a heavy effect for a still version under 768px is invisible to users and measurably kinder to battery and thermals. The canvas demos additionally scale their particle count to the element's area rather than using a fixed number, so a phone draws proportionally fewer than a desktop, and they pause their requestAnimationFrame loop when the element scrolls out of view via IntersectionObserver. Also worth noting: background-attachment: fixed is effectively broken on iOS Safari, so none of these rely on it — the fixed-background effect is achieved with a positioned element instead.
How do these port to React, Vue, Svelte, Next.js and Tailwind?
The 20 pure-CSS backgrounds port with no work at all — copy the markup and the .bga-NN scoped CSS, and they run identically in any framework because there is no JavaScript to place in a lifecycle. Render them as a positioned sibling behind your content with position: absolute; inset: 0; z-index: -1, or as a fixed layer if the background should persist across scroll. For the 5 with JavaScript, wire the init into the framework's mount hook: React uses useEffect(() => { const cleanup = init(); return cleanup }, []) so the canvas loop is cancelled on unmount — forgetting the cleanup is the classic leak here, since a rAF loop keeps running against a detached canvas. Vue 3 uses onMounted plus onBeforeUnmount, Svelte uses onMount returning the cleanup, and Next.js App Router needs 'use client' on those five since they touch canvas and pointer APIs — the other 20 render fine as server components. In Astro, client:idle suits backgrounds well since they are decorative and should never block interaction. For Tailwind v4, keyframes and the @property registrations belong in a @theme block; positioning and sizing translate directly to utilities.