DEV Community

Cover image for Multi-Layer Cinematic Scroll Scene in Pure CSS
Prahalad S
Prahalad S

Posted on

Multi-Layer Cinematic Scroll Scene in Pure CSS

Let’s go full cinematic: A particle-like scroll experience where multiple morphing blobs float, rotate, scale, and drift across the viewport as you scroll. Each blob will behave independently, creating a dynamic, particle-art scroll effect, all in pure CSS.

HTML

<!-- Multi-layered blobs -->
<div class="blob"></div>
<div class="blob"></div>
<div class="blob"></div>
<div class="blob"></div>
<div class="blob"></div>

<!-- Sections -->
<section>
  <h2>Welcome to the cinematic scroll art</h2>
</section>

<section>
  <h2>Blobs morph, rotate, scale and change color</h2>
</section>

<section>
  <h2>Fully scroll-tied animation with pure CSS</h2>
</section>

<section>
  <h2>Each blob moves independently, layered for depth</h2>
</section>

<section>
  <h2>This is interactive CSS artwork!</h2>
</section>
Enter fullscreen mode Exit fullscreen mode

CSS

body {
  margin: 0;
  font-family: system-ui, sans-serif;
  overflow-x: hidden;
  scroll-behavior: smooth;
  background: #0f172a;
  color: white;
}

section {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  text-align: center;
  position: relative;
}

h2 {
  anchor-name: --section-anchor; /* anchor for scroll-tied animation */
  z-index: 10;
  position: relative;
}

/* Base blob style */
.blob {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(0deg) scale(1);
  border-radius: 50%;
  filter: blur(70px);
  z-index: 1;
  animation-timeline: scrollTimeline;
  position-anchor: --section-anchor;
  scroll-timeline-name: scrollTimeline;
  scroll-timeline-axis: block;
  scroll-timeline: auto;
  animation-duration: 1;
  animation-fill-mode: both;
}

/* Individual blobs with unique size, gradient, animation */
.blob:nth-child(1) {
  width: 40vw;
  height: 40vw;
  background: linear-gradient(135deg, #0ea5a4, #3b82f6);
  animation-name: morph1;
}

.blob:nth-child(2) {
  width: 35vw;
  height: 35vw;
  background: linear-gradient(135deg, #f97316, #facc15);
  animation-name: morph2;
}

.blob:nth-child(3) {
  width: 45vw;
  height: 45vw;
  background: linear-gradient(135deg, #d946ef, #8b5cf6);
  animation-name: morph3;
}

.blob:nth-child(4) {
  width: 30vw;
  height: 30vw;
  background: linear-gradient(135deg, #22c55e, #14b8a6);
  animation-name: morph4;
}

.blob:nth-child(5) {
  width: 50vw;
  height: 50vw;
  background: linear-gradient(135deg, #f43f5e, #f97316);
  animation-name: morph5;
}

/* Scroll timeline for all blobs */
@scroll-timeline scrollTimeline {
  source: auto;
  orientation: block;
}

/* Keyframe animations for each blob */
@keyframes morph1 {
  0% {
    border-radius: 50% 50% 40% 60% / 60% 40% 50% 50%;
    transform: translate(-50%, -50%) rotate(0deg) scale(1);
  }
  25% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: translate(-50%, -50%) rotate(10deg) scale(1.05);
  }
  50% {
    border-radius: 40% 60% 60% 40% / 40% 60% 50% 50%;
    transform: translate(-50%, -50%) rotate(-10deg) scale(0.95);
  }
  75% {
    border-radius: 55% 45% 50% 50% / 50% 50% 55% 45%;
    transform: translate(-50%, -50%) rotate(5deg) scale(1.02);
  }
  100% {
    border-radius: 50% 50% 40% 60% / 60% 40% 50% 50%;
    transform: translate(-50%, -50%) rotate(0deg) scale(1);
  }
}

@keyframes morph2 {
  0% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(0deg) scale(1);
  }
  25% {
    border-radius: 55% 45% 60% 40% / 40% 60% 50% 50%;
    transform: rotate(-8deg) scale(1.03);
  }
  50% {
    border-radius: 50% 50% 40% 60% / 60% 40% 55% 45%;
    transform: rotate(6deg) scale(0.97);
  }
  75% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: rotate(-4deg) scale(1.01);
  }
  100% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(0deg) scale(1);
  }
}

@keyframes morph3 {
  0% {
    border-radius: 55% 45% 50% 50% / 50% 50% 55% 45%;
    transform: rotate(0deg) scale(1);
  }
  25% {
    border-radius: 50% 50% 60% 40% / 60% 40% 50% 50%;
    transform: rotate(12deg) scale(1.04);
  }
  50% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(-10deg) scale(0.96);
  }
  75% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: rotate(8deg) scale(1.02);
  }
  100% {
    border-radius: 55% 45% 50% 50% / 50% 50% 55% 45%;
    transform: rotate(0deg) scale(1);
  }
}

@keyframes morph4 {
  0% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: rotate(0deg) scale(1);
  }
  25% {
    border-radius: 50% 50% 40% 60% / 60% 40% 50% 50%;
    transform: rotate(-6deg) scale(1.03);
  }
  50% {
    border-radius: 55% 45% 50% 50% / 50% 50% 55% 45%;
    transform: rotate(6deg) scale(0.97);
  }
  75% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(-3deg) scale(1.01);
  }
  100% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: rotate(0deg) scale(1);
  }
}

@keyframes morph5 {
  0% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(0deg) scale(1);
  }
  25% {
    border-radius: 60% 40% 50% 50% / 50% 50% 60% 40%;
    transform: rotate(7deg) scale(1.05);
  }
  50% {
    border-radius: 50% 50% 60% 40% / 60% 40% 50% 50%;
    transform: rotate(-7deg) scale(0.95);
  }
  75% {
    border-radius: 55% 45% 50% 50% / 50% 50% 55% 45%;
    transform: rotate(3deg) scale(1.02);
  }
  100% {
    border-radius: 40% 60% 50% 50% / 50% 50% 40% 60%;
    transform: rotate(0deg) scale(1);
  }
}

/* Text floating above blobs */
section h2 {
  z-index: 10;
  position: relative;
  mix-blend-mode: difference;
}

Enter fullscreen mode Exit fullscreen mode

🌟 Features:-

  • 8 independent morphing blobs
  • Different sizes, shapes, gradients, rotations, scaling
  • Scroll-tied animation
  • Fully driven by position-anchor + scroll-timeline
  • Depth & layering
  • Blobs overlap with blur to create a 3D particle-like effect
  • Dynamic color gradients
  • Each blob changes color subtly as you scroll
  • Text interacts visually
  • mix-blend-mode: difference makes text pop over the moving blobs
  • Pure CSS

Working Demo

Top comments (0)