Introduction
Fluid and organic animations are among the most impressive effects in modern web design. Unlike classic linear animations, they mimic the natural movements of liquids, creating captivating visual experiences.
In this comprehensive tutorial, we will explore 5 different techniques for creating fluid animations: from simple CSS blob morphing to advanced SVG metaballs, including liquid buttons and lava lamp effects.
This tutorial assumes a basic knowledge of CSS (animations, keyframes) and optionally JavaScript for advanced effects.
1. Blob Morphing (animated border-radius)
Blob morphing is the simplest technique for creating an animated organic shape. It relies on animating the border-radius property with complex values.
Interactive demo
How it works
The key is to use the extended border-radius syntax which allows defining different radii for each corner, with horizontal and vertical values separated by /.
.blob-morph {
width: 200px;
height: 200px;
background: linear-gradient(135deg, #6366f1, #8b5cf6);
/* Syntax: top-left top-right bottom-right bottom-left
/ same vertical values */
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
animation: blobMorph 8s ease-in-out infinite;
box-shadow: 0 0 60px rgba(99, 102, 241, 0.4);
}
@keyframes blobMorph {
0%, 100% {
border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
}
25% {
border-radius: 30% 60% 70% 40% / 50% 60% 30% 60%;
}
50% {
border-radius: 50% 60% 30% 60% / 30% 40% 70% 50%;
}
75% {
border-radius: 40% 60% 50% 40% / 60% 50% 30% 70%;
}
}
2. Metaballs Effect (SVG filter)
The metaballs effect simulates liquid droplets that merge when they get close. This technique uses an SVG filter feGaussianBlur combined with feColorMatrix to create the illusion of merging.
Interactive demo
The SVG filter explained
The secret of metaballs relies on two steps:
- feGaussianBlur: blurs the shapes so they visually overlap
- feColorMatrix: increases contrast to recreate sharp edges while preserving the merge
<svg viewBox="0 0 400 250">
<defs>
<filter id="goo">
<!-- Blurs the shapes -->
<feGaussianBlur
in="SourceGraphic"
stdDeviation="10"
result="blur" />
<!-- Increases alpha contrast -->
<feColorMatrix
in="blur"
mode="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 18 -7" />
</filter>
</defs>
<g filter="url(#goo)">
<circle class="metaball-1" cx="150" cy="125" r="45" fill="#6366f1" />
<circle class="metaball-2" cx="250" cy="125" r="35" fill="#6366f1" />
<circle class="metaball-3" cx="200" cy="100" r="25" fill="#6366f1" />
</g>
</svg>
.metaball-1 {
animation: metaball1 4s ease-in-out infinite;
}
.metaball-2 {
animation: metaball2 4s ease-in-out infinite;
}
.metaball-3 {
animation: metaball3 5s ease-in-out infinite;
}
@keyframes metaball1 {
0%, 100% { transform: translate(0, 0); }
50% { transform: translate(30px, 20px); }
}
@keyframes metaball2 {
0%, 100% { transform: translate(0, 0); }
50% { transform: translate(-25px, 15px); }
}
@keyframes metaball3 {
0%, 100% { transform: translate(0, 0); }
33% { transform: translate(20px, -15px); }
66% { transform: translate(-15px, 10px); }
}
3. Liquid Button
The liquid button simulates filling with a fluid on hover. The effect uses pseudo-elements with rotation animations to create realistic waves.
Interactive demo
.liquid-btn-wrapper {
position: relative;
border: 2px solid #6366f1;
border-radius: 50px;
overflow: hidden;
}
.liquid-btn {
position: relative;
padding: 18px 45px;
font-size: 1.1rem;
font-weight: 600;
color: white;
background: transparent;
border: none;
cursor: pointer;
overflow: hidden;
border-radius: 50px;
}
.liquid-btn span {
position: relative;
z-index: 2;
}
.liquid-btn .liquid {
position: absolute;
top: -80px;
left: 0;
width: 100%;
height: 200px;
background: #6366f1;
box-shadow: inset 0 0 50px rgba(0, 0, 0, 0.4);
transition: top 0.5s ease;
}
/* Vagues animees */
.liquid-btn .liquid::before,
.liquid-btn .liquid::after {
content: '';
position: absolute;
width: 200%;
height: 200%;
top: 0;
left: 50%;
transform: translateX(-50%);
background: rgba(10, 10, 15, 1);
}
.liquid-btn .liquid::before {
border-radius: 45%;
animation: liquidWave 5s linear infinite;
}
.liquid-btn .liquid::after {
border-radius: 40%;
background: rgba(10, 10, 15, 0.5);
animation: liquidWave 10s linear infinite;
}
.liquid-btn:hover .liquid {
top: -120px;
}
@keyframes liquidWave {
0% { transform: translateX(-50%) rotate(0deg); }
100% { transform: translateX(-50%) rotate(360deg); }
}
4. Wave Animation
Wave animation is perfect for transition sections or footers. It uses animated SVG layers with different speeds to create a depth effect.
Interactive demo
.wave-container {
width: 100%;
height: 200px;
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #1a1a2e, #0f0f1a);
}
.wave {
position: absolute;
bottom: 0;
left: 0;
width: 200%;
height: 100px;
background: url("data:image/svg+xml,...");
background-size: 50% 100%;
animation: waveMove 8s linear infinite;
opacity: 0.6;
}
/* Layers with different speeds */
.wave:nth-child(2) {
bottom: 10px;
animation-duration: 6s;
animation-direction: reverse;
opacity: 0.4;
}
.wave:nth-child(3) {
bottom: 20px;
animation-duration: 10s;
opacity: 0.2;
}
@keyframes waveMove {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
5. Lava Lamp Effect
The lava lamp effect recreates the famous lava lamps of the 60s-70s. Blobs rise and fall with organic deformations, creating a hypnotic atmosphere.
Interactive demo
.lava-lamp {
width: 120px;
height: 280px;
background: linear-gradient(180deg, #1a1a2e, #0a0a0f);
border-radius: 60px;
position: relative;
overflow: hidden;
border: 3px solid #2a2a3e;
box-shadow:
0 0 40px rgba(99, 102, 241, 0.2),
inset 0 0 60px rgba(0, 0, 0, 0.5);
}
.lava-blob {
position: absolute;
border-radius: 50%;
filter: blur(8px);
}
.lava-blob-1 {
width: 60px;
height: 60px;
background: radial-gradient(circle, #6366f1, #4f46e5);
bottom: 20px;
left: 50%;
transform: translateX(-50%);
animation: lavaRise1 8s ease-in-out infinite;
}
@keyframes lavaRise1 {
0%, 100% {
bottom: 20px;
width: 60px;
height: 60px;
border-radius: 50%;
}
25% {
width: 50px;
height: 80px;
border-radius: 40% 40% 50% 50%;
}
50% {
bottom: 180px;
width: 55px;
height: 55px;
border-radius: 50%;
}
75% {
width: 50px;
height: 70px;
border-radius: 50% 50% 40% 40%;
}
}
Best practices
Fluid animations are visually impressive but can impact performance. Here are the essential rules to follow.
Performance
- Limit SVG filters: metaballs are expensive, avoid having too many on a page
- Use
will-changesparingly for animated elements - Prefer
transformover properties that trigger reflow (top, left, width) - Test on mobile: less powerful devices may struggle
Accessibility
Always respect user preferences regarding animations. Here is the code to include systematically:
/* Disable animations for sensitive users */
@media (prefers-reduced-motion: reduce) {
.blob-morph,
.metaball,
.liquid,
.wave,
.lava-blob {
animation: none;
}
/* Static alternative for the liquid button */
.liquid-btn .liquid {
top: 0;
}
}
Fast looping animations can trigger seizures in epileptic people. Keep animations slow (> 3 seconds per cycle) and avoid flashes.
Design tips
- One major effect per section to avoid visual overload
- Harmonize colors with your existing palette
- Dark background recommended for better contrast
- Long durations (5-10s) for a soothing effect, short (2-3s) to energize
Conclusion
Fluid animations bring an organic and modern dimension to your interfaces. From simple blob morphing to complex SVG metaballs, each technique has its use:
- Blob morphing: ideal for background decorations or avatars
- Metaballs: perfect for loaders or dynamic visualizations
- Liquid button: excellent for premium CTAs
- Waves: section transitions and footers
- Lava lamp: decorative elements and retro-futuristic atmosphere
Feel free to combine these techniques and experiment with timings and colors to create unique effects tailored to your project.
Find over 50 fluid effects ready to use in our effects library, with copyable and customizable code.