The what, why, and how to use scrollama.js for your next scrollytelling story.

What

Scrollama is a modern and lightweight JavaScript library for scrollytelling using IntersectionObserver in favor of scroll events. Using IntersectionObserver abstracts element-in-view detection and removes the need to monitor scroll events, which contribute towards a sluggish experience. It offers three main features:

Step triggers: Fires an event when an element crosses a visible threshold.

Fires an event when an element crosses a visible threshold. Step progress: Fires events more granularly from 0-100% completion of a step.

Fires events more granularly from 0-100% completion of a step. Sticky graphic: Convenience functions for the opinionated (but popular) scrollytelling sticky graphic pattern.

It is vanilla JS so there are no dependencies like jQuery or D3. Although IntersectionObserver is a bleeding edge technology, Scrollama is polyfilled for browsers without support yet.

Why

Scrollytelling can be complicated to implement and difficult to make performant. The goal of this library is to provide a simple interface for creating scroll-driven interactives and improve user experience by reducing scroll jank. It offers (optional) methods to implement the common scrollytelling pattern to reduce more involved DOM calculations. For lack of a better term, I refer to it as the sticky graphic pattern, whereby the graphic scrolls into view, becomes "stuck" for a duration of steps, then exits and "unsticks" when the steps conclude.

How

Enough talk, time for the good stuff. While you can take a look at the documentation for basic usage, the remainder of this post will be a step-by-step guide to putting together an entire scrollytelling story with scrollama, including the HTML and CSS. Please note that this is a barebones, desktop-centric implementation, please read my post on responsive scrollytelling best practices for things to consider for mobile.

HTML

Inside of #scroll there are two main elements, the graphic container .scroll__graphic and the text container .scroll__text . The graphic here is a container for the actual visual presentation (chart). This is useful for positioning non-full screen elements as you will see shortly. The text is simply a container for each step element .step . The step elements are used to trigger the graphic to change.

I like to put the data attribute data-step with information that tells the JS how to change the graphic when it is triggered. This could be mapped to an array or object in your JS with more detailed data or actions.

CSS

Relatively positioning the parent container is important so that anything that any absolutely positioned children will be relative to where the parent is, not the body.

The graphic container is absolutely positioned, so it will be at the very top of the parent container to start. The height will be set in JS to be 100% of the viewport. Adding a 3D transform reduces some janky jump stuff when going from fixed to absolute position. We add the class .is-fixed in the JS when the should stick, and .is-bottom When the graphic should unstick and lock into place when we scroll passed the section.

Although you can put whatever you want inside the graphic container, here is a common way to add a non-fullscreen, vertically-centered chart to the mix. The width and height are set in JS.

There is no necessary CSS for the text container and the steps. The layout can take on any size, or spacing you prefer. Here is a basic left-aligned approach for an example.

JS

Okay, now we can get into the guts of it and implement scrollama. Here is a top-level look at the structure. Then we will break down what goes on inside each function.

The structure should be pretty straight forward. There are a few "global" variables, a function to handle resize, a few functions to handle the scrollama callback events, and a function to set things up.

Inside the init function, we force a resize to update dom elements, then we initialize the scrollama instance. The only required option is the step paramenter. The sticky graphic pattern however requires the other three dom elements.

The main thing to note here is that this is where you can start highly customizing your presentation and layout of the graphics and charts. For example, you don't need to set the height of the steps via JS, you could simply add more margin on the elements.

The last piece of the puzzle is the scrollama callback functions. In the first one, we can trigger changes to the chart by handling which step becomes active. In the enter and exit callback functions, we stick and unstick the graphic, respectively.

And there you have it! You can see this in action and take a look at the entire code. There are also many different ways to approach this pattern. I have documented a few examples you can check, including other ways to use scrollama. Be sure to read the full documentation!