{ CF }

12 CSS Scroll Animations

Cinematic Image Wipe

Full-viewport frames revealed by a directional clip-path wipe that alternates side to side, captions riding in a beat behind.

CSS + JS MIT licensed

Cinematic Image Wipe the 11th of 12 designs in the 12 CSS Scroll Animations collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.

Live preview

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div class="intro">
  <div class="tag">A Cinematic Sequence</div>
  <h1>Frames<br>That Wipe In</h1>
</div>

<section class="frame">
  <div class="media m1"></div>
  <div class="cap">
    <div class="no">Reel 01</div>
    <h2>Dusk Over the Ridge</h2>
    <p>The first frame slides in from the left, edge sweeping across the image like a curtain pulled fast.</p>
  </div>
</section>

<section class="frame">
  <div class="media m2"></div>
  <div class="cap">
    <div class="no">Reel 02</div>
    <h2>Cold Harbour Light</h2>
    <p>The wipe reverses — entering from the right, the direction alternating frame to frame.</p>
  </div>
</section>

<section class="frame">
  <div class="media m3"></div>
  <div class="cap">
    <div class="no">Reel 03</div>
    <h2>Violet Hour Interior</h2>
    <p>A long easing curve gives the reveal weight, the way a film cut lands rather than snaps.</p>
  </div>
</section>

<section class="frame">
  <div class="media m4"></div>
  <div class="cap">
    <div class="no">Reel 04</div>
    <h2>Embers, After</h2>
    <p>The caption rides in a beat behind the wipe — image first, words second.</p>
  </div>
</section>

<div class="end">— End of Sequence —</div>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
body{background:#070707;font-family:'Archivo',sans-serif;color:#fff;overflow-x:hidden}

.intro{
  height:60vh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;gap:1rem;
}
.intro .tag{
  font-size:11px;letter-spacing:0.3em;text-transform:uppercase;
  color:#666;
}
.intro h1{
  font-family:'Anton',sans-serif;font-size:clamp(40px,8vw,110px);
  line-height:0.95;letter-spacing:0.01em;text-transform:uppercase;
}

/* each frame is full-viewport, image revealed by a wipe */
.frame{
  position:relative;height:118vh;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
}
.media{
  position:absolute;inset:0;
  /* clip starts collapsed; widens on .in */
  clip-path:inset(0 100% 0 0);
  transition:clip-path 1.35s cubic-bezier(0.76,0,0.24,1);
}
.frame.in .media{clip-path:inset(0 0 0 0)}
.frame:nth-child(even) .media{clip-path:inset(0 0 0 100%)}
.frame:nth-child(even).in .media{clip-path:inset(0 0 0 0)}

/* atmospheric "photographs" */
.m1{background:linear-gradient(135deg,#3A1C71,#D76D77 55%,#FFAF7B)}
.m2{background:linear-gradient(135deg,#0F2027,#203A43 55%,#2C5364)}
.m3{background:linear-gradient(135deg,#42275A,#734B6D)}
.m4{background:linear-gradient(135deg,#1F1C18,#8E0E00 60%,#1F1C18)}
.media::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse at center,transparent 30%,rgba(0,0,0,0.55))
}

/* caption rides in behind the wipe */
.cap{
  position:relative;z-index:2;text-align:center;
  opacity:0;transform:translateY(28px);
  transition:opacity 0.8s ease 0.6s,transform 0.8s ease 0.6s;
}
.frame.in .cap{opacity:1;transform:none}
.cap .no{
  font-family:'Anton',sans-serif;font-size:14px;
  letter-spacing:0.2em;color:rgba(255,255,255,0.55);margin-bottom:0.6rem;
}
.cap h2{
  font-family:'Anton',sans-serif;text-transform:uppercase;
  font-size:clamp(34px,6vw,84px);line-height:1;letter-spacing:0.01em;
}
.cap p{
  margin-top:1rem;font-size:14px;color:rgba(255,255,255,0.7);
  max-width:34ch;margin-left:auto;margin-right:auto;line-height:1.6;
}

.end{
  height:50vh;display:flex;align-items:center;justify-content:center;
  font-family:'Anton',sans-serif;font-size:clamp(24px,4vw,52px);
  text-transform:uppercase;color:#1F1F1F;
}
const io=new IntersectionObserver((entries)=>{
  entries.forEach(e=>{
    if(!e.isIntersecting)return;
    e.target.classList.add('in');
    io.unobserve(e.target);
  });
},{threshold:0.35});
document.querySelectorAll('.frame').forEach(el=>io.observe(el));

Search CodeFronts

Loading…