Trigger animations with Intersection Observer API
There are already a few excellent articles and examples about the Intersection Observer API on CSS Tricks or Codepen, but I want to give you a little snippet on how to animate elements when they enter the visible viewport.
It’s pretty common to see a website where things happen on scroll, be it used for animations, lazy-loading images, infinite scrolling, etc. At Liquid Light we normally use a library like ScrollReveal to achieve those things, but these can be replaced with this API, since this is now finally supported in all major browsers.
Here's a simple example that shows circles fading-in/out when they become partially visible in the viewport. The JavaScript uses to API to add and remove a CSS class of isVisible
to the element when it is 50% visible.
See the Pen Trigger animation on scroll with IntersectionObserver API by Liquid Light (@liquidlight) on CodePen.
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>Code
This section contains the code used in the example, in case the CodePen demo isn’t working.
HTML
<h1>Scroll down</h1>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
CSS
:root {
--base: #202050;
--border: #ccc;
}
body {
display: flex;
align-items: center;
flex-direction: column;
margin-top: 10rem;
}
.box {
width: 30vh;
height: 30vh;
margin: 20vh 0;
border: 0.2rem solid var(--border);
border-radius: 50%;
transition: background 0.8s ease,
border 0.4s ease;
}
.box.isVisible {
border-color: var(--base);
background-color: var(--base);
}
JS
const options = {
root: null, // use the document's viewport as the container
rootMargin: '0px', // % or px - offsets added to each side of the intersection
threshold: 0.5 // percentage of the target element which is visible
}
let callback = (entries) => {
entries.forEach(entry => {
// If entry (box) is visible - according with the params set in `options`
// then adds `isVisible` class to box
// otherwise removes `isVisible` class
if(entry.isIntersecting) {
entry.target.classList.add('isVisible');
} else {
entry.target.classList.remove('isVisible');
}
});
}
// Create the intersection observer instance by calling its constructor and passing it a
// callback function to be run whenever a threshold is crossed in one direction or the other:
let observer = new IntersectionObserver(callback, options);
// Get all the `.box` from DOM and attach the observer to these
document.querySelectorAll('.box')
.forEach(box => { observer.observe(box) });
### Further reading:
-
João Augusto
Senior Front-end Developer