How to create scroll animations without a library

by Nick Ciliak on

There are tons of scroll animation libraries out there (I've even written a guide to the best ones) so it might seem like you have to use one if you want to implement scroll animations. But is it possible to create scroll-based animations without using a third-party JavaScript library?

Yes: adding scroll-based animations to your page is totally possible without using a library.

By using a library, you can often save time when implementing your animations. You can also take advantage of performance optimizations that are built into the library. However, when you create them from scratch, you have unlimited flexibility to create the animations exactly the way you want them. Plus, when you build from scratch, you won't be including any unnecessary code that you might be if you used a library.

If you are implementing a page with a lot of scroll animations, you want to use a library. You'll not only save time, but you'll be able to reuse a lot more code and benefit from the performance optimizations a library can provide.

When to implement scroll animations from scratch

If you only need to add a few animations, you're more likely to be a contender to build from scratch, without using a library.

If page speed is a big concern for your project, it might be better to build from scratch, because using a scroll animation library will add additional size to your page. However, there are plenty of small libraries out there, and if you end up reimplementing most of the features that the library provides anyway, you should consider just using the library. If you can't find a small enough library that has only the exact features that you need, then you could just build it from scratch.

Additionally, any time you use a third-party JavaScript library, you add another dependency to your project that is likely not fully under your control. This can be an issue as your project ages: if the package becomes unsupported and bug-ridden in the future, it can cause your project to break as well. If something like this is a concern for your project, you might be better off implementing your animation from scratch.

Here are a few examples of how to implement scroll animations without using a library.

Scroll-triggered animations without a library

If you want an element to animate in some way when it enters or exits the viewport, you can use Intersection Observer to add or remove a class with a CSS animation or transition.

Here's an example:

// Create the observer
var observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Add the CSS class that has your animation
entry.target.classList.add('fade-in');
return;
}

entry.target.classList.remove('fade-in');
})
});

// Observe the element
var element = document.getElementById('my-element');
observer.observe(element);

If you only want the animation to happen once, instead of every time the element is scrolled in and out of the viewport, you can skip removing the class and call observer.unobserve(entry.target) to stop observing the element after the class has been added.

My full guide for how to make scroll animations using Intersection Observer can be found here: How to trigger a CSS animation on scroll.

Scroll-bound animations without a library

If you want to create a scroll-bound animation without a library, you can use a scroll event listener with a callback function that transforms your element based on the distance the page has been scrolled.

Every time the user scrolls the page, the scroll event will be fired. In the scroll event callback, you can check the scroll distance and then change an element's style.

As the user continues to scroll, the element will continue to change, giving the illusion of motion.

Here's an example where an element's opacity is bound to the scroll position:

window.addEventListener('scroll', function() {
var element = document.getElementById('my-element');
var distanceToTop = window.pageYOffset + element.getBoundingClientRect().top;
var elementHeight = element.offsetHeight;
var scrollTop = document.documentElement.scrollTop;

var opacity = 1;

if (scrollTop > distanceToTop) {
opacity = 1 - (scrollTop - distanceToTop) / elementHeight;
}

if (opacity >= 0) {
element.style.opacity = opacity;
}
});

For a full demo and explanation of this technique, check out my tutorial for how to fade an element out on scroll.