Aurora-mesh: A subtle background that doesn't turn your site into a SaaS landing page
How to add an atmospheric gradient background to an editorial portfolio without breaking its minimalist tone. Tradeoffs and the final masked-fade implementation.
When I look at sites like Vercel, Linear, or Resend, the background almost always has a subtle gradient mesh — soft color blobs that "breathe." Combined with typography, it creates a sense of depth and "expensiveness." I wanted the same on gmasich.ru.
First thought — grab a CodePen WebGL snippet and stick it behind the hero. Stop.
Why that's a bad idea
My site is built in an editorial "CTO Document" style — large serif (Source Serif 4), monochrome palette, §01–§05 section markers, asymmetric grids, hairline rules. The main value of this aesthetic is that it doesn't look like a SaaS landing. Any bright blob in the center would instantly turn the site into one of a thousand Vercel clones.
And there's a second consideration — from Emil Kowalski (Sonner, Vaul):
Hero is visible on every page load. Any bright background animation = noise on every visit.
Solution: aurora-mesh with a feathered fade-out
What I chose:
- Three radial gradients with
blur(90px)— three color blobs - Light theme: warm palette (peach/sky/rose), opacity 0.45
- Dark theme: cool palette (blue/violet/cyan), opacity 0.4
- Very slow 38s
transform: translate3d— ≤2% shift, almost subliminal position: fixed+mask-image: linear-gradient(to bottom, black 55%, transparent 95%)— dissolves below the fold, no sharp termination at section boundaries
The key detail is the mask. Without it, the gradient terminated with a horizontal line at the Hero/About boundary:
.bg-aurora {
position: fixed;
inset: -10% -10% 0 -10%;
height: 130vh;
pointer-events: none;
z-index: 0;
opacity: 0.45;
filter: blur(90px) saturate(1.1);
background:
radial-gradient(40% 50% at 22% 30%, hsla(28, 90%, 70%, 0.35), transparent 70%),
radial-gradient(35% 45% at 78% 65%, hsla(200, 70%, 70%, 0.25), transparent 70%),
radial-gradient(30% 40% at 55% 85%, hsla(340, 60%, 75%, 0.2), transparent 70%);
mask-image: linear-gradient(to bottom, black 0%, black 55%, transparent 95%);
animation: aurora-drift 38s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
}
And of course — prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
.bg-aurora { animation: none; }
}
What I learned
- Don't put it in the Hero — aurora should live behind the entire
<main>, otherwise it gets clipped at section boundaries (even withoverflow: hidden, because the blur creates an optical halo beyond the bounding box). - Don't steal someone else's palette — Vercel blue works for Vercel because their entire identity is blue. On a monochrome editorial site, cool pastels work better than warm.
- The mask matters more than the colors — without
mask-imagethe cutoff is always visible, no matter what colors and blur you use.
This isn't WebGL, Three.js, or a shader. It's three CSS gradients and transform: translate3d. Works on any device, doesn't burn CPU after the first animation cycle, requires no JS.
Sometimes "expensive" means four lines of CSS placed in the right spot.
Comments are powered by Giscus + GitHub. Clicking transfers data to GitHub Inc. (USA). No click — no transfer.