Triggering on-scroll CSS animations efficiently using JavaScript's IntersectionObserver API

Back to all posts
10th February 2020

Animating elements into view as a user scrolls down the page has long been a popular pattern, and for good reason - with minimal effort it can breathe a bit of life into an otherwise fairly static experience.

The only problem with this, historically, has been triggering these animations efficiently. The two most common methods for as long as I can remember have been listening to the document scroll event and, slightly more recently, hooking into the requestAnimationFrame API. These both have their uses, but as methods which run hundreds of times a second, there are inevitably performance implications. This might be close to imperceptible to the average user but that little bit of jank introduced, has always irritated me.

Enter, IntersectionObserver. This API allows you to define an element, define an observer and then trigger some arbitrary code when your conditions are met. The real beauty is that this code is fired only when it needs to - massively improving scroll performance and completely eliminating jank.

Here's the code I use to handle the subtle fade/translate animation on this website:

function handleIntersection(entries, observer){
        if(e.isIntersecting === true){

var observer = new IntersectionObserver(handleIntersection, {threshold: 0});
var elementsToObserve = document.querySelectorAll('.hideonload');

Browser support

Unfortunately, as someone who still believes in supporting IE11 (at least in client projects) IntersectionObserver is only supported in Edge onwards, so remember to polyfill if this logic is somehow business critical or, my preference, feature detect and deactivate the functionality entirely.

Comment on this post

I love to talk web. If you have any civil thoughts, corrections or comments on this post, feel free to tweet or DM @fraserboag or, if you prefer, email


Keep up to date

From time to time I post things which people seem to find fairly interesting, stick your email address in the box below and I'll make sure you hear about it!