9

For a poster-style hero I wanted a soft animated gradient mesh, but the usual prompt gives you a seizure-inducing rainbow that makes overlaid text unreadable. The animation also pinned the CPU because it animated background-position on a giant image.

What worked: constrain the palette to two analogous hues plus a neutral, animate only a couple of radial gradients via CSS custom properties with @property, keep the motion slow and low-amplitude, and enforce a contrast overlay so text stays legible. Reduced-motion freezes it to a single tasteful still.

Shipped it behind an article header. Prompt below, happy to hear how you'd make it cheaper still.

THE PROMPT
Generate a subtle animated gradient-mesh background in pure CSS for a hero section. Constraints:
- Palette: two analogous hues + one neutral, defined as CSS custom properties. Muted, low saturation. No rainbow, no more than 3 colors.
- Build the mesh from 2-3 layered `radial-gradient()`s on one element. Animate their positions by registering angle/position vars with `@property` and transitioning them (so the gradient itself animates, not `background-position` on an image).
- Motion: slow (12-20s loop), low amplitude (positions drift <= 15%), `ease-in-out`. It should feel like it's breathing, not strobing.
- Legibility: include a semi-opaque overlay (or `color-mix` scrim) so any text on top keeps >= 4.5:1 contrast. Show the overlay rule.
- `@media (prefers-reduced-motion: reduce)`: freeze to a single static, still-attractive frame (no animation).
- No images, no JS, GPU-friendly. Explain in one line why animating registered custom properties is smoother than animating the gradient string directly.

1 Answer

6

Nice restraint on the palette. If you want it even cheaper, render the mesh on a small element (say 60vw) with filter: blur(40px) and scale it up with transform instead of painting full-viewport gradients. The blur hides the low resolution and the GPU loves the smaller paint area. Just keep the blurred layer behind a solid scrim so the blur edges don't creep into your text zone.

THE PROMPT
Add: paint the mesh on a 60vw element, `filter: blur(40px)`, `transform: scale(1.6)`, positioned behind a scrim. Animate transform/opacity, not layout.

Your Answer