CSS scroll-driven reveal
Each card animates in as it crosses the viewport, driven entirely by CSS animation-timeline: view(), with no JavaScript.
CSSIntermediate
<p class="hint">Scroll inside this frame</p>
<div class="col">
<div class="card">Card 1</div><div class="card">Card 2</div><div class="card">Card 3</div>
<div class="card">Card 4</div><div class="card">Card 5</div><div class="card">Card 6</div>
</div>
body{display:block;height:auto;padding:40px 0 80px}
.col{width:min(420px,88vw);margin:0 auto;display:grid;gap:34px}
.hint{text-align:center;color:#a6938f;font-size:14px;margin-bottom:18px}
.card{height:160px;border-radius:16px;display:grid;place-items:center;font-size:1.6rem;font-weight:700;color:#270100;background:#f08a5d}
.card:nth-child(even){background:#f3d9c8}.card:nth-child(3n){background:#e8b04c}
@supports (animation-timeline:view()){
.card{animation:enter linear both;animation-timeline:view();animation-range:entry 0% cover 35%}
@keyframes enter{from{opacity:0;transform:translateY(80px) scale(.85)}to{opacity:1;transform:none}}
}
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>CSS scroll-driven reveal</title>
<style>
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{display:grid;place-items:center;background:#140807;color:#fffffc;font:16px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif}
body{display:block;place-items:normal;height:auto;padding:40px 0 80px}
.col{width:min(420px,88vw);margin:0 auto;display:grid;gap:34px}
.hint{text-align:center;color:#a6938f;font-size:14px;margin-bottom:18px}
.card{height:160px;border-radius:16px;display:grid;place-items:center;font-size:1.6rem;font-weight:700;color:#270100;background:#f08a5d}
.card:nth-child(even){background:#f3d9c8}.card:nth-child(3n){background:#e8b04c}
@supports (animation-timeline:view()){
.card{animation:enter linear both;animation-timeline:view();animation-range:entry 0% cover 35%}
@keyframes enter{from{opacity:0;transform:translateY(80px) scale(.85)}to{opacity:1;transform:none}}
}
</style></head>
<body>
<p class="hint">Scroll inside this frame</p>
<div class="col">
<div class="card">Card 1</div><div class="card">Card 2</div><div class="card">Card 3</div>
<div class="card">Card 4</div><div class="card">Card 5</div><div class="card">Card 6</div>
</div>
</body></html>
Good for
Reveal and scrub effects where you want zero script and buttery performance.
Watch out for
Supported in Chrome, Edge and Safari 26+. Wrap it in @supports and let everything stay visible elsewhere.
Accessibility
Wrap motion in @media (prefers-reduced-motion: reduce) and switch it off or shorten it for people who ask for less movement.