Backgrounds✨ Premium

Gradient Morph

A blurred radial-gradient mesh cross-fades between two opposing color palettes — a complete chromatic shift every few seconds.

CSSJSTransition

You'll get access to the interactive demo with a free account.

This effect is part of Effect.Labs — 811 vanilla effects, some free, some premium. Backgrounds has 50 effects, including 6 free. Explore the category →

3 usage examples

Full-screen hero — Creative studio or design agency — Gradient Morph example 1

① Full-screen hero — Creative studio or design agency

WhenThe home page loads and the mesh background covers the full visible height — no interaction needed, the effect animates from the first render.
WhyThe warm-to-cool shift captures the eye without overloading the page: blurred gradients stay behind the text thanks to a scrim, while providing chromatic depth that a solid background cannot offer.
SettingsContainer set to position: absolute; inset: 0, border-radius: 0. Scrim rgba(10,10,15,0.45) to preserve text contrast. JS interval at 4 000 ms for a more soothing transition.
Audio player — Dynamic album artwork — Gradient Morph example 2

② Audio player — Dynamic album artwork

WhenThe track artwork changes or the musical genre shifts (mixed playlist); the player background follows by switching palette to signal the mood change.
WhyThe color mesh evokes abstract album art and music visualizers without any canvas: the soft cross-fade matches any tempo without desynchronization.
SettingsSquare container 160×160 px, border-radius: 16px. Customize scheme-a and scheme-b per the album's dominant color via inline styles. Interval at 5 000 ms to track the song tempo.
Event background — Festival or live stream between sets — Gradient Morph example 3

③ Event background — Festival or live stream between sets

WhenA festival website or stream switches artists: the full-screen background automatically cross-fades to a new palette to reflect the incoming set's energy.
WhyThe large surface maximises the warm→cool chromatic gap — the transition is immediately spectacular at screen scale, no text needed to explain it: the mood shifts, the visual shouts it.
SettingsFull-screen container position: absolute; inset: 0, border-radius: 0. Scrim rgba(0,0,0,.55) on overlay text. JS interval at 6 000–8 000 ms to match set rhythms.

How it works

Each palette is an absolutely positioned div layer with inset: -25% — it bleeds 25% past each edge of the container so the gradients cover the corners uniformly. The layer is filled with four radial-gradient() spots at specific coordinates (top-left, top-right, bottom-center, bottom-left corner) and flattened by filter: blur(30px), which blends the colored halos into a seamless mesh with no visible edges.

The palette swap relies on a CSS opacity 2s ease-in-out transition applied to both layers simultaneously: the entering layer rises from 0 to 1 while the exiting layer drops from 1 to 0 — a true cross-fade with no visible artifact. The .active and .inactive classes are toggled by a short JS interval (setInterval) every ~3.5 seconds.

The warm palette (scheme-a) combines bright red, orange, magenta, and yellow; the cool palette (scheme-b) answers with sky blue, teal, violet, and navy. The two palettes share no colors — the maximal chromatic gap makes the transition spectacular even at a slow pace.

The effect uses neither <canvas> nor requestAnimationFrame: two <div> elements and native CSS properties suffice. The GPU cost is limited to blur filter compositing and opacity transitions — no paint loop runs outside the active transitions.

Accessibility

  • prefers-reduced-motion not present in the provided code — no CSS rule or JS branch detects the system preference. For accessible use, add @media (prefers-reduced-motion: reduce) { .morph-mesh-layer { transition: none } } and stop the setInterval if reduced.
  • The .morph-mesh container has no role or aria-label in the base code — add role="img" aria-label="…" if this element is the main visual identity of the area.
  • The .morph-mesh-label span (text 'MORPH') is purely decorative in the demo; in production, add aria-hidden="true" or remove it.
  • No keyboard interaction or focus management in the code: no tabindex to handle.
  • Text contrast on top: verify per active palette. A semi-transparent scrim (ratio ≥ 4.5:1 WCAG AA) is recommended whenever text rests on the mesh.

Browser compatibility

Requires CSS radial-gradient, filter: blur, and opacity transitions — supported in all modern browsers. Zero external dependencies.

Chrome 88+✓ Full
Firefox 87+✓ Full
Safari 14.1+✓ Full
Edge 88+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

Without JS, the warm palette (<code>scheme-a</code>) stays visible statically — the colored background is present, only the swap disappears. Without <code>filter: blur</code> support (very old browsers), gradients appear sharp but remain colorful.

The code

HTML structure to paste into your page (CSS + JS available with a premium account):

index.html — structure
<div class="morph-mesh" id="morphMesh" role="img" aria-label="Blurred gradient mesh background cycling between two color palettes">
  <div class="morph-mesh-layer scheme-a active" aria-hidden="true"></div>
  <div class="morph-mesh-layer scheme-b inactive" aria-hidden="true"></div>
  <!-- Optional: overlay content -->
</div>
🔒 Unlock the full code — from €2.99 the first month

Full HTML + CSS + JS, copy-paste ready — with hundreds of premium effects.

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
.morph-mesh-layer.scheme-a { background } red, orange, magenta, yellow 4 radial-gradient() making up the warm palette — replace the rgba() values with your brand warm tones.
.morph-mesh-layer.scheme-b { background } sky blue, teal, violet, navy 4 radial-gradient() making up the cool palette — replace with your brand cool tones or a second brand variant.
.morph-mesh-layer { filter: blur(…) } blur(30px) Blur intensity: reduce to 12 px for a sharper mesh, increase to 50 px for an even softer atmospheric fade.
.morph-mesh-layer { inset: … } -25% Layer bleed past the container — increase to -40% for denser corner coverage, reduce to -10% for a more centered mesh.
.morph-mesh-layer { transition: opacity … } opacity 2s ease-in-out Duration and easing of the cross-fade: 0.8 s for a snappy switch, 4 s for a near-imperceptible fade.
setInterval(toggle, delay) ~3 500 ms Palette swap frequency — adjust the delay in ms to your desired rhythm (6 000 ms = slow & contemplative, 1 500 ms = energetic & dynamic).
.morph-mesh { border-radius } 16px Container corner radius: 0 for full-bleed edge-to-edge, 50% for a circular blob (e.g. avatar or badge).

FAQ

Partially. Without JS, the warm palette (scheme-a) stays displayed statically via opacity: 1 in the CSS — the colored background is present. Only the swap disappears: it requires a short script (~10 lines) that toggles the .active/.inactive classes via setInterval.
Yes. Add a third layer <div class="morph-mesh-layer scheme-c"> with its own radial-gradient() values, initialize it at opacity: 0, then cycle the JS through 3 states (A→B→C→A…). The CSS transition applies identically to each layer.
Set the .morph-mesh to position: absolute; inset: 0; width: 100%; height: 100% inside a position: relative; overflow: hidden container. Set border-radius to 0 and layer inset to -30% or more so the gradients cover the corners at every viewport size.