Animation on Scroll with Intersection Observer API
By Harsh Rohila
- 3 minutes read - 552 wordsRecently, in one of my websites I implemented below type of animation on scroll. Try scrolling below list of cards. Notice that the cards are animating only when they are in view.
In this post I am going to explain its implementation. It’s using one of the Browser APIs, called Intersection Observer API.
What is Intersection Observer API?
- The Intersection Observer API is an API using which we can run a callback if an element intersects any other element.
- The other element can be any ancestor element or viewport .
- The API also provides a way to specify, on how much intersection we want to run the callback.
The animation which I created above is using viewport to check intersection.
Now let’s look into code. The code is starting from main()
const observer = getObserver()
const listElements = document.querySelectorAll('li')
for (let i = 0; i < listElements.length; i++) {
observer.observe(listElements[i])
}
getObserver()
gets an instance ofIntersectionObserver
class. We will look into that function later below.- Then the code loops over all list elements and adds them as target to this observer using the
observe
function. - So this code is simply observing all list elements with an observer.
Now in getObserver()
function, we have
let observer = new IntersectionObserver(callback, options)
- The instance of
IntersectionObserver
is created with 2 parameters, callback and options. - Options is for configuring the observer. In our case it looks like below
const options = {
threshold: 0.2
}
- The threshold is for specifying the extent of intersection. Here 0.2 means 20% intersection. Here, we have not used the
root
option to specify any ancestor element, so by default it considers intersection with the viewport. In short, it will check for 20% intersection(of listElement) with the viewport.
Now, the callback looks like below
const callback = entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('show-up')
} else {
entry.target.classList.remove('show-up')
}
})
}
- The callback is having
entries
parameter, which is an array. It is an array because we can add multiple target elements usingobserve
function onIntersectionObserver
’s object. So each entry represents an entry for a target element(in our case targets are the list elements). - Note that, the callback can be called for each list element in 2 cases. When element is scrolled into view, it will be the case of 0.0 intersection to 0.2 intersection. And other case is when list element is scrolled out of view. From 0.2 intersection to 0.0. Its called both times as both times its crossing the 0.2 intersection mark. To differentiate between these 2,
isIntersecting
is provided in each entry. IfisIntersecting
is true, it means the element is scrolled into view. - So when the element is scrolled into view,
show-up
class is added to it and when it is scrolled out of viewshow-up
class is removed.
Now, let’s look into CSS.
li {
transition: opacity 1s;
opacity: 0;
transform: scale(0.8);
transition-property: opacity, transform;
&.show-up {
opacity: 1;
transform: scale(1);
}
}
SCSS is used in this example. CSS equivalent of
&.show-up
in above case isli.show-up
- CSS transition is used for animation.
li
element having default/initial styles withoutshow-up
class. Withshow-up
class, styles for final state are given.- Transition is used for
opacity
andtransform
properties.
Resources
- MDN Docs - For knowing more about Intersection Observer API