An animated background is one of the fastest ways to make a page feel considered. It is also one of the fastest ways to add four megabytes to a page that had no business being heavy.
The usual approach is a looping MP4 behind a dark overlay. It works, and it costs you: the file has to download before anything moves, it decodes continuously while visible, and on a laptop that means measurable battery drain for a decoration.
Almost every effect people use video for can be done in CSS or a small canvas, at zero network cost.
What CSS can do on its own
More than most people expect:
- Drifting gradient blobs. Two or three large radial gradients with heavy
blur(), each on its own slowtransformkeyframe loop. This is the aurora look, and it is perhaps 30 lines of CSS. - Grid and dot fields. Repeating linear or radial gradients as
background-image, with amask-imagefading them out at the edges so there is no hard cut. - Marquees and conveyor belts. One
@keyframestranslating a duplicated track by-50%. No JavaScript, no library. - Noise and grain. A tiled SVG
feTurbulenceas a data URI, at low opacity. - Mesh-gradient washes. Several overlapping conic or radial gradients with different blend modes.
The rule that makes these cheap: animate transform and opacity, nothing else. Both are handled by the compositor. Animating background-position, width, or filter forces a repaint of a large area every frame, and that is where the smooth version and the janky version diverge.
When you actually want canvas or WebGL
Particle fields, fluid simulation, and anything responding to the pointer in real time need a canvas. That is a fair trade — you are getting behavior CSS cannot express.
What is not a fair trade is reaching for a 600 KB 3D library to draw a few floating dots.
The three things to specify
When prompting for a background, name these or you will get a video tag:
- The technique — "pure CSS, no canvas, no video file, no external assets"
- The compositing budget — "animate only
transformandopacity" - The reduced-motion branch — "under
prefers-reduced-motion: reduce, freeze at the initial state"
That third one is not optional politeness. A continuously moving full-page background is exactly the kind of thing that triggers discomfort for people who set that preference.
The overlay question
Most animated backgrounds sit under content, which means they need to lose a contrast fight on purpose. A dark scrim — rgba(5, 5, 5, 0.6) or thereabouts — over the whole background layer is standard.
Worth thinking about before you build the effect, not after: if the result is going to be pressed down 70% by an overlay anyway, an elaborate effect is wasted. Something simple and cheap will look identical through the scrim.
A stacking trap
Backgrounds are usually position: fixed; z-index: 0. In-flow content that is not positioned paints before positioned elements — so your text can end up underneath the background layer even though the z-index arithmetic looks right.
The fix is to give the content wrapper position: relative and a z-index above the background. Worth knowing before you spend twenty minutes on the z-index values.
Our animated background prompts are written to produce zero-request implementations — CSS where CSS suffices, canvas only where it does not, reduced-motion handled in every one.
Browse the free prompts — several backgrounds are open to everyone.