20 CSS Gradient Text Designs 05 / 20

CSS Lava Lamp Radial Gradient Text

A slowly drifting radial gradient simulates molten lava inside the text glyphs, using animated CSS custom properties to move the gradient hotspot.

Pure CSS MIT licensed
Live Demo Open in tab
Open in playground

The code

<div class="gt-05">
  <span class="gt-05__label">Lava lamp radial gradient</span>
  <h1 class="gt-05__blob">MAGMA</h1>
  <p class="gt-05__tagline">Molten radial gradient text</p>
  <div class="gt-05__orbs">
    <div class="gt-05__orb"></div>
    <div class="gt-05__orb"></div>
    <div class="gt-05__orb"></div>
  </div>
  <span class="gt-05__orb-label">radial motion</span>
</div>
.gt-05, .gt-05 *, .gt-05 *::before, .gt-05 *::after {
  margin: 0; padding: 0; box-sizing: border-box;
}
.gt-05 {
  --bg: #0d0208;
  --hot1: #ff3b00;
  --hot2: #ff8800;
  --hot3: #ffcc00;
  --cool: #3b0a0a;
  font-family: 'Syne', sans-serif;
  background: var(--bg);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
  padding: 3rem 2rem;
}
.gt-05__label {
  font-family: 'Syne Mono', monospace;
  font-size: .65rem;
  letter-spacing: .25em;
  text-transform: uppercase;
  color: #ff330040;
}
.gt-05__blob {
  font-size: clamp(3rem, 12vw, 8rem);
  font-weight: 800;
  line-height: 1;
  background: radial-gradient(
    circle at var(--x, 30%) var(--y, 40%),
    var(--hot3) 0%,
    var(--hot2) 25%,
    var(--hot1) 55%,
    #6b0000 100%
  );
  background-size: 200% 200%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gt-05-blob 6s ease-in-out infinite;
}
.gt-05__tagline {
  font-family: 'Syne Mono', monospace;
  font-size: clamp(.7rem, 2vw, 1rem);
  background: linear-gradient(90deg, var(--hot1), var(--hot2), var(--hot3));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: gt-05-pulse 3s ease-in-out infinite alternate;
  letter-spacing: .15em;
}
.gt-05__orbs {
  display: flex;
  gap: 1.5rem;
  align-items: flex-end;
}
.gt-05__orb {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--hot3), var(--hot1));
  animation: gt-05-rise 3s ease-in-out infinite;
  position: relative;
}
.gt-05__orb::after {
  content: '';
  position: absolute;
  inset: 15% 20% 40% 20%;
  background: rgba(255,255,255,.25);
  border-radius: 50%;
  transform: rotate(-30deg);
}
.gt-05__orb:nth-child(1) { width: 40px; height: 40px; animation-delay: -.5s; }
.gt-05__orb:nth-child(2) { width: 70px; height: 70px; animation-delay: -1s; }
.gt-05__orb:nth-child(3) { width: 50px; height: 50px; animation-delay: -1.8s; }
.gt-05__orb-label {
  font-family: 'Syne Mono', monospace;
  font-size: .6rem;
  letter-spacing: .1em;
  color: var(--hot2);
  background: linear-gradient(90deg, var(--hot1), var(--hot3));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
@keyframes gt-05-blob {
  0%   { --x: 30%; --y: 40%; }
  25%  { --x: 60%; --y: 70%; }
  50%  { --x: 70%; --y: 30%; }
  75%  { --x: 40%; --y: 60%; }
  100% { --x: 30%; --y: 40%; }
}
@keyframes gt-05-pulse {
  0%   { opacity: .6; }
  100% { opacity: 1; }
}
@keyframes gt-05-rise {
  0%, 100% { transform: translateY(0) scale(1); }
  50%       { transform: translateY(-20px) scale(1.05); }
}
@media (prefers-reduced-motion: reduce) {
  .gt-05__blob, .gt-05__tagline, .gt-05__orb { animation: none; }
}

How this works

The gradient is defined as radial-gradient(circle at var(--x) var(--y), ...) where --x and --y are custom properties. The keyframe gt-05-blob sets new percentage values for --x and --y at each step, which modern browsers interpolate as they do any other animatable custom property. The hotspot appears to drift organically because the path follows an irregular quadrilateral rather than a loop.

Animated custom properties on a gradient require the browser to re-evaluate the gradient each frame — this is a paint operation, not a compositor operation. Keep the animated element to a reasonable size and avoid stacking many such elements to stay within paint budget. Orb elements below the headline use only transform animation and are compositor-safe.

Customize

  • Add more waypoints to gt-05-blob (at 33%, 66% etc.) for a more complex drift path; the gradient hotspot will trace the full polygon.
  • Change the glow palette by editing --hot1 through --hot3 — try neon green (#00ff88) and deep purple for a toxic variant.
  • Slow the drift to 12s for a meditative molten-glass feel, or speed to 2s for a frenetic plasma effect.

Watch out for

  • Animating CSS custom properties that feed into gradients is a paint operation — avoid using this on large hero backgrounds at mobile scale where repaint areas are huge.
  • Safari before 15.4 does not interpolate custom properties in gradients smoothly — the hotspot will jump between keyframe positions rather than drift. Test on Safari 15.3 and consider a simpler fallback.
  • The radial-gradient at position syntax (circle at X% Y%) requires the full at keyword; shorthand omitting it will fall back to center.

Browser support

ChromeSafariFirefoxEdge
79+ 15.4+ 75+ 79+

Smooth custom-property interpolation in gradients requires Safari 15.4+; earlier Safari shows a jump-cut animation instead.

Search CodeFronts

Loading…