30 CSS Keyframe Animations 30 / 30
CSS Animated Gradient Mesh Background
Animated gradient mesh using floating radial-gradient orbs on a dark base: full hero scene, four colour-variant cards (purple, pink, green, gold) and a rainbow gradient text strip.
This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.
The code
<div class="kf-30">
<h2>CSS Animated Gradient Mesh</h2>
<!-- Hero -->
<div class="hero-mesh">
<div class="mesh-bg">
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="orb orb-3"></div>
<div class="orb orb-4"></div>
</div>
<div class="hero-content">
<h3>Gradient Mesh</h3>
<p>pure CSS · no canvas · no SVG</p>
</div>
</div>
<!-- Cards -->
<div class="cards">
<div class="mesh-card mc-a">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Purple · Cyan</div>
<div class="card-title">Analytics</div>
</div>
<div class="mesh-card mc-b">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Pink · Orange</div>
<div class="card-title">Creative</div>
</div>
<div class="mesh-card mc-c">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Green · Teal</div>
<div class="card-title">Growth</div>
</div>
<div class="mesh-card mc-d">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Gold · Warm</div>
<div class="card-title">Premium</div>
</div>
</div>
<!-- Gradient text -->
<div class="gradient-text-demo">
<div class="grad-text">VIVID</div>
</div>
</div> <div class="kf-30">
<h2>CSS Animated Gradient Mesh</h2>
<!-- Hero -->
<div class="hero-mesh">
<div class="mesh-bg">
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="orb orb-3"></div>
<div class="orb orb-4"></div>
</div>
<div class="hero-content">
<h3>Gradient Mesh</h3>
<p>pure CSS · no canvas · no SVG</p>
</div>
</div>
<!-- Cards -->
<div class="cards">
<div class="mesh-card mc-a">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Purple · Cyan</div>
<div class="card-title">Analytics</div>
</div>
<div class="mesh-card mc-b">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Pink · Orange</div>
<div class="card-title">Creative</div>
</div>
<div class="mesh-card mc-c">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Green · Teal</div>
<div class="card-title">Growth</div>
</div>
<div class="mesh-card mc-d">
<div class="card-bg"></div>
<div class="card-orb"></div>
<div class="card-orb"></div>
<div class="card-label">Gold · Warm</div>
<div class="card-title">Premium</div>
</div>
</div>
<!-- Gradient text -->
<div class="gradient-text-demo">
<div class="grad-text">VIVID</div>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;700;900&display=swap');
.kf-30 *, .kf-30 *::before, .kf-30 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.kf-30 {
font-family: 'Inter', sans-serif;
background: #050508;
color: #fff;
padding: 48px 24px;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
}
.kf-30 h2 {
font-size: 1rem;
color: #333;
letter-spacing: 3px;
text-transform: uppercase;
font-weight: 300;
}
/* ── 1: Full hero gradient mesh ── */
.kf-30 .hero-mesh {
width: 100%;
max-width: 960px;
min-height: 320px;
border-radius: 24px;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.kf-30 .mesh-bg {
position: absolute;
inset: 0;
background: #0a0a14;
}
/* Floating gradient orbs */
.kf-30 .orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
mix-blend-mode: screen;
}
.kf-30 .orb-1 {
width: 400px; height: 400px;
background: radial-gradient(circle, rgba(124,106,247,0.5) 0%, transparent 70%);
top: -100px; left: -80px;
animation: kf-30-orb1 8s ease-in-out infinite;
}
.kf-30 .orb-2 {
width: 350px; height: 350px;
background: radial-gradient(circle, rgba(233,30,140,0.4) 0%, transparent 70%);
bottom: -80px; right: -60px;
animation: kf-30-orb2 10s ease-in-out infinite;
}
.kf-30 .orb-3 {
width: 300px; height: 300px;
background: radial-gradient(circle, rgba(0,212,255,0.35) 0%, transparent 70%);
top: 30%; left: 40%;
transform: translate(-50%, -50%);
animation: kf-30-orb3 7s ease-in-out infinite;
}
.kf-30 .orb-4 {
width: 250px; height: 250px;
background: radial-gradient(circle, rgba(0,212,106,0.3) 0%, transparent 70%);
bottom: 10%; left: 20%;
animation: kf-30-orb4 12s ease-in-out infinite;
}
@keyframes kf-30-orb1 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(80px, 60px) scale(1.1); }
66% { transform: translate(-40px, 80px) scale(0.9); }
}
@keyframes kf-30-orb2 {
0%, 100% { transform: translate(0, 0) scale(1); }
40% { transform: translate(-100px, -60px) scale(1.15); }
70% { transform: translate(50px, -40px) scale(0.85); }
}
@keyframes kf-30-orb3 {
0%, 100% { transform: translate(-50%, -50%) scale(1); }
50% { transform: translate(-40%, -60%) scale(1.2); }
}
@keyframes kf-30-orb4 {
0%, 100% { transform: translate(0, 0); }
50% { transform: translate(80px, -50px) scale(1.1); }
}
.kf-30 .hero-content {
position: relative;
z-index: 2;
text-align: center;
}
.kf-30 .hero-content h3 {
font-size: clamp(2rem, 6vw, 3.5rem);
font-weight: 900;
letter-spacing: 2px;
background: linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.7) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.kf-30 .hero-content p {
font-size: 1rem;
color: rgba(255,255,255,0.45);
margin-top: 8px;
letter-spacing: 2px;
font-weight: 300;
}
/* ── 2: Card variants ── */
.kf-30 .cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
width: 100%;
max-width: 960px;
}
.kf-30 .mesh-card {
border-radius: 20px;
overflow: hidden;
position: relative;
min-height: 200px;
padding: 24px;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.kf-30 .mesh-card .card-bg {
position: absolute;
inset: 0;
}
.kf-30 .mesh-card .card-orb {
position: absolute;
border-radius: 50%;
filter: blur(40px);
mix-blend-mode: screen;
}
/* Card A: Purple + cyan */
.kf-30 .mc-a .card-bg { background: #080814; }
.kf-30 .mc-a .card-orb:nth-child(2) { width: 200px; height: 200px; background: rgba(124,106,247,0.6); top: -60px; left: -60px; animation: kf-30-ca1 6s ease-in-out infinite; }
.kf-30 .mc-a .card-orb:nth-child(3) { width: 150px; height: 150px; background: rgba(0,212,255,0.4); bottom: -40px; right: -40px; animation: kf-30-ca2 8s ease-in-out infinite; }
@keyframes kf-30-ca1 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(40px,30px)} }
@keyframes kf-30-ca2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(-30px,-40px)} }
/* Card B: Pink + orange */
.kf-30 .mc-b .card-bg { background: #0e0810; }
.kf-30 .mc-b .card-orb:nth-child(2) { width: 180px; height: 180px; background: rgba(233,30,140,0.6); top: -50px; right: -50px; animation: kf-30-cb1 7s ease-in-out infinite; }
.kf-30 .mc-b .card-orb:nth-child(3) { width: 140px; height: 140px; background: rgba(255,107,53,0.5); bottom: -30px; left: -30px; animation: kf-30-cb2 9s ease-in-out infinite; }
@keyframes kf-30-cb1 { 0%,100%{transform:translate(0,0) scale(1)} 50%{transform:translate(-40px,30px) scale(1.1)} }
@keyframes kf-30-cb2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(40px,-30px)} }
/* Card C: Green + teal */
.kf-30 .mc-c .card-bg { background: #050e0a; }
.kf-30 .mc-c .card-orb:nth-child(2) { width: 200px; height: 200px; background: rgba(0,212,106,0.5); bottom: -60px; left: -40px; animation: kf-30-cc1 8s ease-in-out infinite; }
.kf-30 .mc-c .card-orb:nth-child(3) { width: 160px; height: 160px; background: rgba(0,180,220,0.4); top: -40px; right: -40px; animation: kf-30-cc2 6s ease-in-out infinite; }
@keyframes kf-30-cc1 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(50px,-40px)} }
@keyframes kf-30-cc2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(-40px,40px)} }
/* Card D: Gold + warm */
.kf-30 .mc-d .card-bg { background: #0d0a05; }
.kf-30 .mc-d .card-orb:nth-child(2) { width: 220px; height: 220px; background: rgba(247,201,72,0.5); top: -80px; right: -40px; animation: kf-30-cd1 9s ease-in-out infinite; }
.kf-30 .mc-d .card-orb:nth-child(3) { width: 160px; height: 160px; background: rgba(255,140,60,0.4); bottom: -40px; left: -20px; animation: kf-30-cd2 7s ease-in-out infinite; }
@keyframes kf-30-cd1 { 0%,100%{transform:translate(0,0) scale(1)} 50%{transform:translate(-40px,50px) scale(0.9)} }
@keyframes kf-30-cd2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(50px,-30px)} }
.kf-30 .card-label {
position: relative;
z-index: 2;
font-size: 0.72rem;
color: rgba(255,255,255,0.4);
letter-spacing: 2px;
text-transform: uppercase;
}
.kf-30 .card-title {
position: relative;
z-index: 2;
font-size: 1.2rem;
font-weight: 700;
color: rgba(255,255,255,0.85);
margin-top: 4px;
}
/* ── 3: Gradient text animation ── */
.kf-30 .gradient-text-demo {
text-align: center;
}
.kf-30 .grad-text {
font-size: clamp(2rem, 8vw, 4rem);
font-weight: 900;
background: linear-gradient(90deg,
#7c6af7, #e91e8c, #ff6b35, #f7c948, #00d46a, #00d4ff, #7c6af7
);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: kf-30-gradshift 4s linear infinite;
letter-spacing: 4px;
}
@keyframes kf-30-gradshift {
0% { background-position: 0% center; }
100% { background-position: 200% center; }
}
@media (prefers-reduced-motion: reduce) {
.kf-30 .orb,
.kf-30 .card-orb,
.kf-30 .grad-text { animation: none; }
} @import url('https://fonts.googleapis.com/css2?family=Inter:wght@200;300;400;700;900&display=swap');
.kf-30 *, .kf-30 *::before, .kf-30 *::after { box-sizing: border-box; margin: 0; padding: 0; }
.kf-30 {
font-family: 'Inter', sans-serif;
background: #050508;
color: #fff;
padding: 48px 24px;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
gap: 40px;
}
.kf-30 h2 {
font-size: 1rem;
color: #333;
letter-spacing: 3px;
text-transform: uppercase;
font-weight: 300;
}
/* ── 1: Full hero gradient mesh ── */
.kf-30 .hero-mesh {
width: 100%;
max-width: 960px;
min-height: 320px;
border-radius: 24px;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.kf-30 .mesh-bg {
position: absolute;
inset: 0;
background: #0a0a14;
}
/* Floating gradient orbs */
.kf-30 .orb {
position: absolute;
border-radius: 50%;
filter: blur(60px);
mix-blend-mode: screen;
}
.kf-30 .orb-1 {
width: 400px; height: 400px;
background: radial-gradient(circle, rgba(124,106,247,0.5) 0%, transparent 70%);
top: -100px; left: -80px;
animation: kf-30-orb1 8s ease-in-out infinite;
}
.kf-30 .orb-2 {
width: 350px; height: 350px;
background: radial-gradient(circle, rgba(233,30,140,0.4) 0%, transparent 70%);
bottom: -80px; right: -60px;
animation: kf-30-orb2 10s ease-in-out infinite;
}
.kf-30 .orb-3 {
width: 300px; height: 300px;
background: radial-gradient(circle, rgba(0,212,255,0.35) 0%, transparent 70%);
top: 30%; left: 40%;
transform: translate(-50%, -50%);
animation: kf-30-orb3 7s ease-in-out infinite;
}
.kf-30 .orb-4 {
width: 250px; height: 250px;
background: radial-gradient(circle, rgba(0,212,106,0.3) 0%, transparent 70%);
bottom: 10%; left: 20%;
animation: kf-30-orb4 12s ease-in-out infinite;
}
@keyframes kf-30-orb1 {
0%, 100% { transform: translate(0, 0) scale(1); }
33% { transform: translate(80px, 60px) scale(1.1); }
66% { transform: translate(-40px, 80px) scale(0.9); }
}
@keyframes kf-30-orb2 {
0%, 100% { transform: translate(0, 0) scale(1); }
40% { transform: translate(-100px, -60px) scale(1.15); }
70% { transform: translate(50px, -40px) scale(0.85); }
}
@keyframes kf-30-orb3 {
0%, 100% { transform: translate(-50%, -50%) scale(1); }
50% { transform: translate(-40%, -60%) scale(1.2); }
}
@keyframes kf-30-orb4 {
0%, 100% { transform: translate(0, 0); }
50% { transform: translate(80px, -50px) scale(1.1); }
}
.kf-30 .hero-content {
position: relative;
z-index: 2;
text-align: center;
}
.kf-30 .hero-content h3 {
font-size: clamp(2rem, 6vw, 3.5rem);
font-weight: 900;
letter-spacing: 2px;
background: linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.7) 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
.kf-30 .hero-content p {
font-size: 1rem;
color: rgba(255,255,255,0.45);
margin-top: 8px;
letter-spacing: 2px;
font-weight: 300;
}
/* ── 2: Card variants ── */
.kf-30 .cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
width: 100%;
max-width: 960px;
}
.kf-30 .mesh-card {
border-radius: 20px;
overflow: hidden;
position: relative;
min-height: 200px;
padding: 24px;
display: flex;
flex-direction: column;
justify-content: flex-end;
}
.kf-30 .mesh-card .card-bg {
position: absolute;
inset: 0;
}
.kf-30 .mesh-card .card-orb {
position: absolute;
border-radius: 50%;
filter: blur(40px);
mix-blend-mode: screen;
}
/* Card A: Purple + cyan */
.kf-30 .mc-a .card-bg { background: #080814; }
.kf-30 .mc-a .card-orb:nth-child(2) { width: 200px; height: 200px; background: rgba(124,106,247,0.6); top: -60px; left: -60px; animation: kf-30-ca1 6s ease-in-out infinite; }
.kf-30 .mc-a .card-orb:nth-child(3) { width: 150px; height: 150px; background: rgba(0,212,255,0.4); bottom: -40px; right: -40px; animation: kf-30-ca2 8s ease-in-out infinite; }
@keyframes kf-30-ca1 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(40px,30px)} }
@keyframes kf-30-ca2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(-30px,-40px)} }
/* Card B: Pink + orange */
.kf-30 .mc-b .card-bg { background: #0e0810; }
.kf-30 .mc-b .card-orb:nth-child(2) { width: 180px; height: 180px; background: rgba(233,30,140,0.6); top: -50px; right: -50px; animation: kf-30-cb1 7s ease-in-out infinite; }
.kf-30 .mc-b .card-orb:nth-child(3) { width: 140px; height: 140px; background: rgba(255,107,53,0.5); bottom: -30px; left: -30px; animation: kf-30-cb2 9s ease-in-out infinite; }
@keyframes kf-30-cb1 { 0%,100%{transform:translate(0,0) scale(1)} 50%{transform:translate(-40px,30px) scale(1.1)} }
@keyframes kf-30-cb2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(40px,-30px)} }
/* Card C: Green + teal */
.kf-30 .mc-c .card-bg { background: #050e0a; }
.kf-30 .mc-c .card-orb:nth-child(2) { width: 200px; height: 200px; background: rgba(0,212,106,0.5); bottom: -60px; left: -40px; animation: kf-30-cc1 8s ease-in-out infinite; }
.kf-30 .mc-c .card-orb:nth-child(3) { width: 160px; height: 160px; background: rgba(0,180,220,0.4); top: -40px; right: -40px; animation: kf-30-cc2 6s ease-in-out infinite; }
@keyframes kf-30-cc1 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(50px,-40px)} }
@keyframes kf-30-cc2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(-40px,40px)} }
/* Card D: Gold + warm */
.kf-30 .mc-d .card-bg { background: #0d0a05; }
.kf-30 .mc-d .card-orb:nth-child(2) { width: 220px; height: 220px; background: rgba(247,201,72,0.5); top: -80px; right: -40px; animation: kf-30-cd1 9s ease-in-out infinite; }
.kf-30 .mc-d .card-orb:nth-child(3) { width: 160px; height: 160px; background: rgba(255,140,60,0.4); bottom: -40px; left: -20px; animation: kf-30-cd2 7s ease-in-out infinite; }
@keyframes kf-30-cd1 { 0%,100%{transform:translate(0,0) scale(1)} 50%{transform:translate(-40px,50px) scale(0.9)} }
@keyframes kf-30-cd2 { 0%,100%{transform:translate(0,0)} 50%{transform:translate(50px,-30px)} }
.kf-30 .card-label {
position: relative;
z-index: 2;
font-size: 0.72rem;
color: rgba(255,255,255,0.4);
letter-spacing: 2px;
text-transform: uppercase;
}
.kf-30 .card-title {
position: relative;
z-index: 2;
font-size: 1.2rem;
font-weight: 700;
color: rgba(255,255,255,0.85);
margin-top: 4px;
}
/* ── 3: Gradient text animation ── */
.kf-30 .gradient-text-demo {
text-align: center;
}
.kf-30 .grad-text {
font-size: clamp(2rem, 8vw, 4rem);
font-weight: 900;
background: linear-gradient(90deg,
#7c6af7, #e91e8c, #ff6b35, #f7c948, #00d46a, #00d4ff, #7c6af7
);
background-size: 200% auto;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: kf-30-gradshift 4s linear infinite;
letter-spacing: 4px;
}
@keyframes kf-30-gradshift {
0% { background-position: 0% center; }
100% { background-position: 200% center; }
}
@media (prefers-reduced-motion: reduce) {
.kf-30 .orb,
.kf-30 .card-orb,
.kf-30 .grad-text { animation: none; }
}How this works
The hero mesh is four absolutely-positioned .orb circles with radial-gradient(circle, rgba(...) 0%, transparent 70%) backgrounds, each blurred with filter: blur(60px) and blended via mix-blend-mode: screen on a dark #0a0a14 base. Per-orb keyframes translate them on independent paths over 7-12s with subtle scale(0.85 → 1.2) variation, so the mesh constantly reshapes.
The variant cards apply the same pattern at smaller scale — two orbs per card, blurred 40px, with paired translate keyframes that drift in opposing directions. The rainbow text uses background: linear-gradient(90deg, #7c6af7, #e91e8c, #ff6b35, #f7c948, #00d46a, #00d4ff, #7c6af7) at background-size: 200% auto, clipped to the text via -webkit-background-clip: text, with background-position: 0% → 200% sliding the colours through the glyphs.
Customize
- Recolour the mesh by editing the
rgba(124,106,247,0.5)values inside.orb-1through.orb-4. - Slow the mesh drift by changing
kf-30-orb1from8sto16sfor a more meditative background. - Adjust the blur amount from
60pxto90pxfor an even softer mesh, or30pxfor sharper colour blobs. - Modify the rainbow text gradient stops to a brand-specific palette via the
.grad-textbackground declaration. - Speed up the text shimmer by changing
kf-30-gradshiftfrom4sto2sfor a more active feel.
Watch out for
filter: blur(60px)on four large orbs is one of the most GPU-expensive things you can do in CSS — disable on low-end devices via@media (max-width: 640px).mix-blend-mode: screenrequires a non-transparent backdrop — placing this mesh over a transparent or video parent breaks the blend.- The
-webkit-background-clip: textapproach for the rainbow text needs the-webkitprefix even in 2026 — Firefox 49+ supports it, but the unprefixedbackground-clip: textstill requires the vendor fallback.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 60+ | 13.1+ | 103+ | 60+ |
background-clip: text and large blur filters together gate the demo — Firefox below 103 renders the mesh but may show seams; safe across the board from 2022 builds.