22 CSS Transition Effects 02 / 22

Slide-In Animation on Scroll

Intersection Observer scroll reveal with six directions — left, right, bottom, top, scale-up and rotate-in — plus stagger delay classes.

CSS + JS MIT licensed
Live Demo Open in tab

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="hero">
  <div class="reveal from-bottom" style="transition-delay:0s">
    <div style="font-family:'Syne Mono';font-size:.75rem;letter-spacing:.3em;color:#a78bfa;margin-bottom:16px;text-transform:uppercase">Scroll animation demo</div>
  </div>
  <div class="reveal from-bottom delay-1">
    <h1>Slide In<em>On Scroll</em></h1>
  </div>
  <div class="reveal from-bottom delay-2">
    <p>Elements animate into view as you scroll down the page — six different entrance directions, all pure CSS transitions triggered by an Intersection Observer.</p>
  </div>
  <div class="reveal from-bottom delay-3">
    <div class="hero-hint">↓ SCROLL DOWN ↓</div>
  </div>
</div>

<section>
  <div class="reveal from-left"><div class="section-label">Features</div></div>
  <div class="reveal from-left delay-1"><h2 class="section-title">Six entrance styles</h2></div>
  <div class="cards">
    <div class="card reveal from-bottom delay-1"><div class="num">01</div><h3>Slide from Left</h3><p>Elements enter from the left edge with a smooth easing curve.</p></div>
    <div class="card reveal from-bottom delay-2"><div class="num">02</div><h3>Slide from Right</h3><p>Content appears from the right, ideal for alternating layouts.</p></div>
    <div class="card reveal from-bottom delay-3"><div class="num">03</div><h3>Slide from Bottom</h3><p>Classic upward reveal — the most widely used scroll animation.</p></div>
    <div class="card reveal scale-up delay-4"><div class="num">04</div><h3>Scale Up</h3><p>Items grow from 88% to 100% for a subtle but satisfying pop.</p></div>
    <div class="card reveal rotate-in delay-5"><div class="num">05</div><h3>Rotate In</h3><p>A slight rotation combined with scale creates a card-flip feel.</p></div>
    <div class="card reveal from-top delay-6"><div class="num">06</div><h3>Slide from Top</h3><p>Dropping elements downward — great for headings and badges.</p></div>
  </div>

  <div class="feature reveal from-bottom">
    <div>
      <h2>Staggered delay system</h2>
      <p>Add <code>.delay-1</code> through <code>.delay-6</code> to children for a choreographed cascade effect. Each step adds 100ms of delay, giving groups of elements a natural rhythm.</p>
    </div>
    <div class="feature-visual">
      <div class="fv-box reveal scale-up delay-1">🎯</div>
      <div class="fv-box reveal scale-up delay-2">✦</div>
      <div class="fv-box reveal scale-up delay-3">◈</div>
      <div class="fv-box reveal scale-up delay-4">⬡</div>
    </div>
  </div>

  <div class="reveal from-left"><div class="section-label">Social proof</div></div>
  <div class="reveal from-left delay-1"><h2 class="section-title">Used by thousands</h2></div>
  <div class="testimonials">
    <div class="testi reveal from-left delay-1"><p>"The stagger delays make the whole page feel alive. Replaced our GSAP dependency with this pure CSS approach."</p><div class="testi-author"><div class="testi-avatar">AK</div><div><div class="testi-name">Alex Kim</div><div class="testi-role">Lead Developer</div></div></div></div>
    <div class="testi reveal from-bottom delay-2"><p>"Buttery smooth on mobile. The reduced-motion support is exactly what we needed for accessibility compliance."</p><div class="testi-author"><div class="testi-avatar">SL</div><div><div class="testi-name">Sara Liu</div><div class="testi-role">UX Engineer</div></div></div></div>
    <div class="testi reveal from-right delay-3"><p>"Implemented in 20 minutes. The Intersection Observer approach means zero layout jank during scroll."</p><div class="testi-author"><div class="testi-avatar">MR</div><div><div class="testi-name">Marcus Reid</div><div class="testi-role">Frontend Architect</div></div></div></div>
  </div>

  <div class="stats reveal scale-up">
    <div class="stat"><div class="big">98%</div><span>Lighthouse score</span></div>
    <div class="stat"><div class="big">6</div><span>Animation types</span></div>
    <div class="stat"><div class="big">0kb</div><span>Dependencies</span></div>
    <div class="stat"><div class="big">A11y</div><span>Reduced motion</span></div>
  </div>
</section>
@import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=Syne+Mono&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:'Syne',sans-serif;background:#f5f0e8;color:#1a1a1a;overflow-x:hidden}

/* scroll reveal base */
.reveal{opacity:0;transition:opacity .7s ease,transform .7s cubic-bezier(.22,1,.36,1)}
.reveal.from-left{transform:translateX(-60px)}
.reveal.from-right{transform:translateX(60px)}
.reveal.from-bottom{transform:translateY(50px)}
.reveal.from-top{transform:translateY(-50px)}
.reveal.scale-up{transform:scale(.88)}
.reveal.rotate-in{transform:rotate(-8deg) scale(.9)}
.reveal.visible{opacity:1 !important;transform:none !important}

/* delays */
.delay-1{transition-delay:.1s}.delay-2{transition-delay:.2s}.delay-3{transition-delay:.3s}
.delay-4{transition-delay:.4s}.delay-5{transition-delay:.5s}.delay-6{transition-delay:.6s}

/* page layout */
.hero{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:40px 24px;background:linear-gradient(160deg,#0f0f1a,#1a0a2e)}
.hero h1{font-size:clamp(3rem,10vw,7rem);font-weight:800;color:#fff;letter-spacing:-.04em;line-height:.9;margin-bottom:24px}
.hero h1 em{color:#a78bfa;font-style:normal;display:block}
.hero p{color:#9ca3af;font-size:1.1rem;max-width:50ch;margin-bottom:32px}
.hero-hint{color:#6b7280;font-family:'Syne Mono';font-size:.8rem;letter-spacing:.2em;animation:trn02-bounce 2s ease-in-out infinite}
@keyframes trn02-bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(8px)}}

section{padding:80px 24px;max-width:1100px;margin:0 auto}

.section-label{font-family:'Syne Mono';font-size:.75rem;letter-spacing:.3em;text-transform:uppercase;color:#a78bfa;margin-bottom:12px}
.section-title{font-size:clamp(2rem,5vw,3.5rem);font-weight:800;letter-spacing:-.03em;margin-bottom:40px;color:#1a1a1a}

/* card grid */
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:24px;margin-bottom:80px}
.card{background:#fff;border-radius:20px;padding:32px;box-shadow:0 4px 24px rgba(0,0,0,.07);position:relative;overflow:hidden}
.card::before{content:'';position:absolute;top:0;left:0;right:0;height:4px;background:var(--accent,#a78bfa)}
.card .num{font-size:3.5rem;font-weight:800;color:var(--accent,#a78bfa);opacity:.15;line-height:1;margin-bottom:8px}
.card h3{font-size:1.15rem;font-weight:700;margin-bottom:8px}
.card p{font-size:.9rem;color:#666;line-height:1.6}
.card:nth-child(1){--accent:#a78bfa}
.card:nth-child(2){--accent:#34d399}
.card:nth-child(3){--accent:#f97316}
.card:nth-child(4){--accent:#f472b6}
.card:nth-child(5){--accent:#38bdf8}
.card:nth-child(6){--accent:#fbbf24}

/* feature strip */
.feature{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:center;margin-bottom:80px;padding:48px;background:#1a0a2e;border-radius:24px;color:#fff}
@media(max-width:640px){.feature{grid-template-columns:1fr}}
.feature h2{font-size:clamp(1.8rem,4vw,2.6rem);font-weight:800;letter-spacing:-.03em;margin-bottom:16px}
.feature p{color:#9ca3af;line-height:1.7}
.feature-visual{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.fv-box{background:linear-gradient(135deg,var(--c1),var(--c2));border-radius:16px;aspect-ratio:1;display:grid;place-items:center;font-size:2rem}
.fv-box:nth-child(1){--c1:#7c3aed;--c2:#a78bfa}
.fv-box:nth-child(2){--c1:#0ea5e9;--c2:#38bdf8}
.fv-box:nth-child(3){--c1:#f97316;--c2:#fb923c}
.fv-box:nth-child(4){--c1:#10b981;--c2:#34d399}

/* testimonial row */
.testimonials{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:20px;margin-bottom:80px}
.testi{background:#1a1a1a;border-radius:16px;padding:28px;color:#fff}
.testi p{font-size:.95rem;line-height:1.6;color:#d1d5db;margin-bottom:16px}
.testi-author{display:flex;align-items:center;gap:12px}
.testi-avatar{width:36px;height:36px;border-radius:50%;background:var(--c,#a78bfa);display:grid;place-items:center;font-size:.8rem;font-weight:700}
.testi:nth-child(1) .testi-avatar{--c:#7c3aed}
.testi:nth-child(2) .testi-avatar{--c:#0ea5e9}
.testi:nth-child(3) .testi-avatar{--c:#10b981}
.testi-name{font-size:.82rem;font-weight:700;color:#f9fafb}
.testi-role{font-size:.72rem;color:#6b7280}

/* stats */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;background:#fff;border-radius:24px;padding:40px;box-shadow:0 4px 30px rgba(0,0,0,.07)}
@media(max-width:640px){.stats{grid-template-columns:1fr 1fr}}
.stat{text-align:center}
.stat .big{font-size:clamp(2rem,5vw,3rem);font-weight:800;color:var(--c,#7c3aed)}
.stat:nth-child(1){--c:#7c3aed}
.stat:nth-child(2){--c:#0ea5e9}
.stat:nth-child(3){--c:#f97316}
.stat:nth-child(4){--c:#10b981}
.stat span{display:block;font-size:.8rem;color:#888;margin-top:4px}

@media (prefers-reduced-motion:reduce){.reveal{transition:none !important;opacity:1 !important;transform:none !important}}
const observer = new IntersectionObserver(entries => {
  entries.forEach(e => { if(e.isIntersecting) { e.target.classList.add('visible'); observer.unobserve(e.target); } });
}, { threshold: 0.15 });
document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
// Trigger hero items which are already in view
document.querySelectorAll('.hero .reveal').forEach(el => el.classList.add('visible'));

Search CodeFronts

Loading…