Scroll-related animations have been used on the web for years. In recent years, they’ve started to become more common, perhaps in part due to devices being higher-performing and thus able to handle more animation.
There are a number of scroll-related technologies out there, so this article’s aim is to provide an overview of them and tools to help choose the one that’s right for you. I’d argue that these technologies can be broken down into two broad categories: ones for specific scroll-related behaviors and ones for more generic scroll-related behaviors.
Technologies for specific scroll-related behaviors
There are a few simple native CSS scroll effects that are supported by modern browsers. In some limited use cases, they can be sufficient for your scroll animation needs.
position: sticky;
If all you need is for an element to stay in the same place on scroll for a portion of the page, using position: sticky
is a good option. It’s straightforward and built into modern browsers. That said, a polyfill is required for IE support and some mobile browsers. For a solid overview, check out this article by Preethi.
CSS parallax
This isn’t a technology as much as a technique, but it’s pretty handy for simple parallax effects where you want different pieces of the page to move at different speeds on scroll. There’s a good write-up of the technique over at DigitalOcean and a bunch of examples on CodePen, like this Firewatch header. The biggest downside for me is that it’s difficult to understand what values to use to set the perspective and transforms in order to get the parallax effect exactly right.
CSS scroll snap points
Scroll snap points allow the browser to snap to particular scroll positions that you set after a user is done with their normal scrolling. This can be helpful for keeping certain elements in view. However, the API is still in flux so be careful to use the most up to date API and be careful about relying on it in production. This CSS-Tricks article by Max Kohler is a good place to learn about it right now.
Smooth scrolling
Smooth scrolling is supported natively when jumping from section to section within a page using window.scrollTo()
in JavaScript or even the scroll-behavior
property in CSS. Generic smooth scrolling that smooths out mouse wheel actions is not supported natively in all browsers at this time. There are various JavaScript libraries that attempt to add smooth scroll support for the mousewheel action, but I’ve yet to find one that is bug-free and plays nicely with all other scroll technologies. Plus, smooth scrolling isn’t always good in the first place.
Technologies for generic scroll behaviors
Currently, there is no way to create or fire generic animations based on the scroll position using just CSS (though there is a proposal that could support some form of generic scroll based animations in CSS in the distant future) or to scrub through part of an animation. As such, if you want to animate elements on scroll, you’ll need to use at least some JavaScript to create the effect you want. There are two broad methods of using JavaScript to fire animations on scroll: using intersection observers and using the scroll
event.
IntersectionObserver
Intersection observers are great if all you need for your animation is information related to whether or not and how much of an element is visible in the viewport. This makes them a good option for reveal animations. Even then, some things are difficult (though not impossible) using intersection observers, such as firing different animations depending on the direction an element enters the viewport. Intersection observers also aren’t very helpful if you want to do any scroll animations when an element is in between and not overlapping with the start and end points.
Using the scroll
event
Using the scroll event will give you the most freedom in controlling animations on scroll. It allows you to affect an element on scroll no matter where it is in terms of the viewport and set up starting and ending points exactly as you need for your project.
With that being said, it can also be intense on performance if it isn’t throttled correctly and doesn’t have a convenient API to create particular behaviors. This is why it’s oftentimes helpful to use a good scrolling library that can handle the throttling for you and give you a more handy API to work with. Some can even handle a lot of the resizing issues for you!
Tools to create generic scroll behaviors
There are a few holistic scrolling libraries that attempt to give you full control over animations on scroll without you having to perform all of the calculations yourself.
ScrollMagic
ScrollMagic provides a relatively simple API to create various effects on scroll and can be hooked into different animation libraries like GSAP and Velocity.js. However, it has become less maintained over the past few years, which lead to the creation of ScrollScene.
ScrollScene
ScrollScene is essentially a wrapper to try and make ScrollMagic and/or the intersection observer more usable. It uses a custom, more maintained version of ScrollMagic and adds additional features like video playback, scene init breakpoints, and scene duration breakpoints. It also makes use of GSAP.
ScrollTrigger
ScrollTrigger is an official GreenSock plugin for GSAP. It has a long list of features and has the most easy to use API of any scroll library (at least to me). Using it, you can have complete control to define where your scroll animations start and end, animate anything (WebGL, canvas, SVG, DOM, whatever) on scroll, pin elements in place while the animation is running, and more. You can even hook it up to smooth scrolling libraries and they will work great together. Plus it has the support of GreenSock and the GreenSock forums.
Notable mention: Locomotive Scroll
While it doesn’t attempt to be as comprehensive of a scrolling library as the other libraries mentioned above, Locomotive Scroll is focused on providing custom smooth scrolling. You can also animate certain properties of DOM objects by adding data attributes or hook into the onscroll
event to animate other types of objects.
In summary
For some particular scroll animation effects, like sticky positioning and parallax, CSS technologies may be sufficient, at least when using a polyfill for browsers that don’t support those properties.
I generally recommend using GSAP’s ScrollTrigger because it can do everything that CSS properties can do, plus much more. ScrollTrigger will handle the browser support and calculations so that you can focus on animating!
Here’s a table covering which tools you can use to create particular effects:
ScrollTrigger | Locomotive Scroll | ScrollScene | ScrollMagic | Intersection observers | Smooth Scrolling | CSS scroll snap points | CSS parallax | position: sticky | |
---|---|---|---|---|---|---|---|---|---|
Pinning | ✅ | ⚪️ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
Parallax effects | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
Scrubbing through animation with easing | ✅ | ⚪️ | ⚪️ | ⚪️ | ⚪️ | ❌ | ❌ | ⚪️ | ❌ |
Snaps scroll position | ✅ | ⚪️ | ⚪️ | ⚪️ | ⚪️ | ❌ | ✅ | ❌ | ❌ |
Smooth scrolling | ⚪️ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ |
Dynamic Batching / Staggering | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ |
Supports horizontal scroll effects | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Here’s a table comparing various other aspects of scroll technology:
ScrollTrigger | Locomotive Scroll | ScrollScene | ScrollMagic | Intersection observers | Smooth scrolling | CSS scroll snap points | CSS parallax | position: sticky | |
---|---|---|---|---|---|---|---|---|---|
Usable in production (good browser support) | ✅ | ⚪️ | ✅ | ✅ | ⚪️ | ⚪️ | ⚪️ | ✅ | ⚪️ |
Complete freedom in animation | ✅ | ⚪️ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Maintained | ✅ | ✅ | ✅ | ❌ | n/a | n/a | n/a | n/a | n/a |
Works with DOM, Canvas, WebGl, SVG | ✅ | ⚪️ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
Works easily with resizing | ✅ | ✅ | ✅ | ⚪️ | ✅ | ✅ | ✅ | ✅ | ✅ |
Restricts animation to relevant section | ✅ | ❌ | ⚪️ | ⚪️ | ✅ | ✅ | ✅ | ❌ | ✅ |
Directionally aware | ✅ | ⚪️ | ✅ | ✅ | ⚪️ | ❌ | ❌ | ❌ | ❌ |
Native technology | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ |
⚪️ = Partial support
❌ = No