As you scroll, photos and text softly appear from below—we’ll make that effect you often see on stylish sites. It looks hard, but the mechanism is the same as the like button from last time. It’s just “add a class when the trigger arrives.” The only difference is that the trigger isn’t a click but entering the screen.
CSS side: prepare the before and after of appearing
First, prepare before appearing (transparent and slightly lower) and after appearing (the normal position) in CSS.
.reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.is-visible {
opacity: 1;
transform: translateY(0);
}opacity: 0 makes it transparent, translateY(24px) shifts it just 24px down. When .is-visible is added, both return to the original—because there’s a transition, that return becomes the “soft” appearance.
JS side: watch for entering the screen
The browser provides a dedicated tool that watches for “whether an element has entered the screen.” That’s IntersectionObserver.
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
}
});
});
document.querySelectorAll('.reveal').forEach((el) => observer.observe(el));It looks long, but read line by line it says this.
| Part | Meaning |
|---|---|
new IntersectionObserver(...) | Hire one watcher |
entry.isIntersecting | ”Is it on screen right now?” (judged with an if statement) |
entry.target.classList.add(...) | If it’s in, add a class to that element |
observer.observe(el) | Ask “please watch this element” |
The querySelectorAll in the last line is the catch-them-all version of querySelector. It catches all the elements with .reveal together and registers them one by one with the watcher.
Let’s see it move
add (only adding) the class.Summary of this lesson
- The scroll effect is really “add a class when it enters the screen”—the same division of roles as the like button
- The watcher is
IntersectionObserver. Register elements withobserve()and judge withisIntersecting - To make it appear once and stay, use
classList.add(only adding)
That rounds out the tools for motion. Next time, as the finale, we’ll learn how to deliver that motion considerately, even to people who find motion difficult.