Boost your CSS animations with Intersection Observer API
CSS animations can be a pain in the 🍑, and what's even worst is to trigger them at the exact moment. For that exact reason, and if I may be perfectly honest with you, I opt for not using them most of the time. However...
Presenting: Intersection Observer API
Before starting, if you need a refresher on what's an API, this is a good place to get info on it
You may think that I'm out of my mind for suggesting that you should use an API for animating CSS but hear me out... GitHub uses it to make their homepage more performant and faster so you know it must be good!
When we usually want to check an element's position in the window we might end up using stuff like
elem.offsetTop or even
elem.getBoundingClientRect() but the truth is that these properties/methods will trigger the browser to calculate the required style and layout (check the whole list of properties that target this and a further explanation here) which creates a performance bottleneck.
A way to circumvent this is by using the Intersection Observer API, which, according to the MDN documentation, 'provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.'. So, basically, we'll just monitor if an element will enter/exit another element/the viewport and that's way easier for the browser to process.
So... How do you do it?
The IntersectionObserver interface can be created very easily and all you have to do is to pass a callback to it and some options. The callback is what decides what will happen to the list of IntersectionObserverEntry objects and the options allow you to control the circumstances in which the callback will be called (please refer to the MDN documentation for full details on this).
For example purposes only, we'll not define our options (which will make them adopt some default values) and we'll simply work with our callback, so our initial setup would be something like this:
Now that we have our expansionObserver, we need to grab the elements that we want to animate. For this we'll use
document.querySelectorAll() and we'll get all the elements with the class
So, on our HTML it would look like this:
After this, we need to tell the
IntersectionObserver that we want to
observe these elements, and since we're using
querySelectorAll() we need to loop over
elementsToExpand and we'll use a
forEach() for it.
if/else statement we wrote on our callback. Here we'll want to style our
elementsToExpand with the animation that they should have like so:
So, this is the whole behaviour that you have to recreate and now all we have to do is to define in our CSS this
And we're done! You can now check the full example in this preview or you can play around with the CodeSandbox yourself! I've added an extra element with a different animation so you could get a full grip of what's happening! 😄
And that's it!
What did you think about the
Intersection Observer API? Will you give it a try on your next project?
Let me know what you thought about this post and feel free to follow me on Twitter 🤘