Atmosphere✨ Premium

Morphing Blob

A pure-CSS organic shape: eight border-radius values morph through an 8-second keyframe cycle with an indigo-to-fuchsia gradient — no script required.

CSSOrganic

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. Atmosphere has 57 effects, including 10 free. Explore the category →

3 usage examples

Hero / Landing — Creative service banner — Morphing Blob example 1

① Hero / Landing — Creative service banner

WhenHomepage of a creative app, AI studio, or design agency: the blob replaces a static hero image for immediate presence with no network request.
WhyThe continuous deformation catches peripheral attention without distracting from the headline; a light scrim keeps it unobtrusive.
Settingswidth: 320px; height: 320px, animation-duration: 12s (calm pace), default indigo-fuchsia gradient.
Testimonials Section — Organic blob behind a client quote — Morphing Blob example 2

② Testimonials Section — Organic blob behind a client quote

WhenAbout or testimonials section of a creative agency: a large blob fills the left half of the frame behind a portrait or quote, creating a striking organic backdrop with no external asset.
WhyAt 280 px the morph is fully legible across half the screen; the indigo-fuchsia gradient reinforces the agency's visual identity and contrasts with the portrait avatar placed on top.
Settingswidth: 280px; height: 280px, animation-duration: 10s, default indigo-fuchsia gradient, opacity: 0.85.
Conversion micro-interaction — Sign-up CTA backdrop — Morphing Blob example 3

③ Conversion micro-interaction — Sign-up CTA backdrop

WhenFinal CTA block on a landing page (newsletter, SaaS, community): the blob appears behind the 'Join' button when it scrolls into the viewport.
WhyThe organic motion behind the CTA creates a visual energy that invites action without disrupting the button or text readability.
Settingswidth: 260px; height: 260px, animation-duration: 10s, opacity: 0.7, orange-rose gradient linear-gradient(135deg, #f97316, #db2777).

How it works

The effect relies entirely on the extended border-radius notation: x1 x2 x3 x4 / y1 y2 y3 y4 sets the horizontal and vertical radii of each corner independently. Four keyframe steps (0%, 25%, 50%, 75%) drive the deformation inside @keyframes morphBlob; the CSS engine interpolates smoothly between them with no imperative code.

The animation uses ease-in-out on the global animation property — not per-step animation-timing-function — which naturally slows each start and end of the cycle and reinforces the impression of a breathing organism rather than a mechanical transition.

The fill is a linear-gradient(135deg, #6366f1, #d946ef) — indigo to fuchsia — drawn diagonally from bottom-left to top-right. The 135° angle accentuates the perception of depth on the ever-shifting silhouette: dark and light corners alternate with each morph.

There is no JavaScript: no requestAnimationFrame, no observer, no script-side state. The animation loop is entirely handled by the browser's rendering engine, guaranteeing optimal GPU performance and seamless integration into any framework.

Accessibility

  • No prefers-reduced-motion in the source code: the animation runs continuously regardless of the system setting. Add to your CSS: @media (prefers-reduced-motion: reduce) { .morph-blob { animation: none; border-radius: 50%; } }
  • The .morph-blob is a purely decorative element with no text or interaction — no keyboard focus trap or navigation issue from the effect itself.
  • The supplied HTML exposes neither aria-hidden nor aria-label. In decorative use, add aria-hidden="true" on the parent container to exclude the blob from the accessibility tree.
  • No text contrast to check on the blob alone — contrast responsibility falls on the overlay content placed by the integrator.
  • No native events (click, focus, keyboard) attached to the blob: the effect is passive, with no risk of a navigation trap.

Browser compatibility

Requires border-radius with slash notation and CSS animations — supported in all modern browsers since 2012.

Chrome 36+✓ Full
Firefox 16+✓ Full
Safari 9+✓ Full
Edge 79+✓ Full
Mobile iOS✓ Full
Android Chrome✓ Full

If CSS animations are not supported, the <code>div.morph-blob</code> renders as a slightly rounded rectangle with the gradient intact — no JS errors, the page stays readable.

The code

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

index.html — structure
<div class="demo-preview" aria-hidden="true">
  <!-- Decorative blob — all mechanics live in CSS -->
  <div class="morph-blob"></div>

  <!-- Overlay content: position absolute on .demo-preview (position: relative) -->
</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
background (.morph-blob, l. 57) linear-gradient(135deg, #6366f1, #d946ef) Gradient colors and angle. E.g. linear-gradient(135deg, #0ea5e9, #22d3ee) for an aquatic feel, or a flat color #6366f1 for a monochrome blob.
animation-duration (.morph-blob, l. 58) 8s Duration of one full morph cycle. 4s = nervous and energetic blob, 16s = slow meditative breathing.
width / height (.morph-blob, l. 55-56) 200px Shape size. Equal values = near-square blob; higher height = vertically elongated blob.
animation-timing-function (.morph-blob, l. 58) ease-in-out Timing curve. linear = constant mechanical morphing, ease-in-out = slowdown at extremes (organic feel).
border-radius 0%/100% (@keyframes, l. 32) 60% 40% 30% 70%/60% 30% 70% 40% Start and end shape (0% and 100% of the cycle). Any combination of 0 to 100% is valid for all 8 values.
border-radius 50% (@keyframes, l. 40) 50% 60% 30%/30% 40% 70% 50% Mid-cycle shape. Changing these values alters the intermediate point furthest from the initial silhouette.

FAQ

No, the effect is 100% CSS. There is no script: the animation is declared in @keyframes morphBlob and applied via animation on .morph-blob. Compatible with Angular, React, Vue, and Svelte — just include the CSS and place <div class="morph-blob"></div> in the DOM.
The source code does not include prefers-reduced-motion. Add to your CSS: @media (prefers-reduced-motion: reduce) { .morph-blob { animation: none; border-radius: 50%; } } — the blob becomes a static circle with the gradient intact.
CSS gradients cannot be directly interpolated between two values. The simplest approach: animate filter: hue-rotate() on .morph-blob with a second @keyframes, which rotates the gradient's hues across the spectrum without touching the effect's structure.