Opens in a new tab

Guide

Animate on scroll with CSS: fade-in, reveal masks and the difference between transitions and animations

How to animate on scroll with CSS: fade-in, slide-in, mask and circle reveals, transitions vs animations, and the no-code version in Bricks.

John Diaz · Updated October 2026 ·

On this page

Every reveal on this page is the same trick underneath: a class gets added when the element reaches the screen, and CSS does the rest. Once you see that, the rest is choosing what the CSS does.

How a CSS animation fires on scroll: a class added when the element enters the viewport

CSS cannot see the scroll. Something watches the element — an IntersectionObserver — and adds a class the moment it appears. The element already has its final style; the class is what releases it.

.reveal {
  opacity: 0;
  translate: 0 24px;
  transition: opacity .5s ease, translate .5s ease;
}

.reveal.is-in {
  opacity: 1;
  translate: 0 0;
}

Animate.css and AOS on scroll: what they do and what they cost

They are not the same thing. Animate.css gives you the keyframes and nothing else — no script, no observer; you add the class yourself. AOS adds the observer too, and with it the part that costs real money: content that starts hidden and only appears if its JavaScript runs.

CSS fade-in animation: keyframes, fade in up, delay and fade out

A fade is opacity from 0 to 1. A fade in up adds a small translate so the element arrives from below. A delay staggers several of them. Keep the distance short — 20 to 40 px reads as arriving; 200 px reads as flying in.

Slide-in from the left, zoom and image entrance animations for heroes and landing pages

Slides and zooms are the same transition with a different starting transform. For a hero image, a slow zoom that keeps running after the entrance (a Ken Burns) gives life without asking for attention; for cards in a grid, a short slide up, staggered, is almost always enough.

CSS reveal animations: mask reveal, circular reveal and image reveal

A reveal uncovers the element instead of moving it, and it is the one family that is not transform and opacity: it animates clip-path. A sweep wipes from one side, a circular reveal opens from a point, blinds split it into strips.

.sweep {
  clip-path: inset(0 100% 0 0);
  transition: clip-path .6s ease;
}

.sweep.is-in {
  clip-path: inset(0 0 0 0);
}

CSS transitions vs animations: when to use each, and where transform fits

TransitionAnimation
What starts itA property changes (a class, a hover)It runs on its own, from keyframes
Can it loop?NoYes
Steps in betweenStart and end onlyAs many keyframes as you want
Good forReveals on scroll, hover statesLoops, multi-step entrances

Transform is neither: it is the property most worth animating, because moving, scaling or rotating with it does not make the browser lay the page out again. Animate transform and opacity; avoid width, height, top and margin.

Reveal on scroll with JavaScript: an IntersectionObserver in a few lines

const io = new IntersectionObserver((entries) => {
  entries.forEach((e) => {
    if (!e.isIntersecting) return;
    e.target.classList.add('is-in');
    io.unobserve(e.target);
  });
}, { threshold: 0.2 });

document.querySelectorAll('.reveal').forEach((el) => io.observe(el));

threshold: 0.2 waits until a fifth of the element is visible, so it does not fire the instant a single pixel appears. unobserve makes it play once.

Pitfalls: content hidden before JavaScript runs, layout shift and animating everything

The snippet above has a real flaw worth naming: if the script never runs, the content stays at opacity 0. A heading nobody can read is worse than a heading that does not move. Guard it: start visible and let the script opt elements in, or hide only under a class the script itself adds.

The other two are easier: animate transform and opacity so nothing shifts, and resist animating every section. When everything moves, nothing is emphasised.

The no-code version in Bricks: entrance animation classes with run once or always, time, delay and stagger

Do it without code

The observer, the keyframes and the guard, already written

Entrance animations gives you the whole pattern from the panel: 66 animations (fades, slides, zooms, Ken Burns, sweeps, circle reveals, blur, bounce, fan, flicker), plus time, delay, viewport trigger, run once or every time, and stagger for children that should take turns.

66 entrance animations

Go further: entrance animations for Bricks, Etch and Gutenberg

Entrance animations shows every one live; text animations does the same for headings, split by letter, word or line; and the scroll animations guide covers the effects that follow the scroll instead of playing once.

What is the difference between a CSS transition and a CSS animation?

A transition interpolates between two states when a property changes (hover, a class toggle); an animation runs keyframes on its own, can loop and does not need a state change. Scroll reveals usually need only a transition plus a class.

What is a good duration for a CSS transition or entrance animation?

Short: a few hundred milliseconds for small elements, a little longer for large sections. Anything that makes the reader wait for content feels slow, whatever the easing.

What is the difference between a transform and a transition?

Transform is the property that moves, scales or rotates an element; transition is how the change in that property is timed. Most scroll animations transition a transform and an opacity.

Can you animate on scroll with CSS alone?

The animation itself is pure CSS, but something has to trigger it when the element enters the viewport: a tiny script that adds a class, or the newer animation-timeline, which browsers do not all support yet.

Does animate.css or AOS slow my site down?

Animate.css is only a stylesheet — hundreds of keyframes you mostly will not use, but no script. AOS also adds a script and hides content until it runs, which is the costlier half.

How do I trigger a CSS animation on scroll in Bricks without code?

Pick an entrance animation in the Fancy Animations controls of the element: fade, slide, zoom, sweep, circle reveal or Ken Burns, with time, delay and run once or always.

Add Bricks Builder animations to your next site

From $179, one payment, every update for life. 14-day refund.