A tiny JavaScript library to enable CSS animations when user scrolls.

This library toggles a class to an element when it appears on viewport when user scrolls. It lets you build CSS transitions or animations launched only when user scrolls on it. Only set a few HTML attributes, and code the rest with your CSS skills.

Note that in order to not be JavaScript dependant, this library add the class when the element is outside of the viewport. This way, if you have a JS error, it’s the default state that will appears on scroll.

Download – 1,73ko
Compressed, for production
Download – 3,69ko
Uncompressed, for development
View on GitHub


The following fake elements are generated randomly just to illustrate what you can do with this library.

The circles are set to be animated several or infinite times, the squares just once. Of course, the animations defined manually are for example. You can make whatever you want in your CSS.

Hover any of them to see their settings in the tooltip. If you want to follow one when you scroll up and down, just click on it.

How to use


<foo data-scroll="class-name">

A CSS class name, added when this element is outside of viewport, is-outside if empty.

<foo data-scroll data-scroll-repeat=" false | true | <number> ">

optional — Specify if the class will be added each time the element appears in viewport or not, or a maximum number of iteration. false by default if not specified.

<foo data-scroll data-scroll-offset=" <number> ">

optional — Specify an offset in pixels to take into account from the top and bottom edges of the viewport. 0 by default if not specified.


<!-- Toggle '.is-outside' class when outside of viewport, just once -->
<div data-scroll> … </div>

<!-- Toggle '.mulder' class when outside of viewport, just once -->
<div data-scroll="mulder"> … </div>

<!-- Toggle '.scully' class each time when outside of viewport -->
<div data-scroll="scully" data-scroll-repeat="true"> … </div>

<!-- Toggle '.alien' class 10 times when outside of 100 pixels
     of top and bottom edges of viewport -->
<div data-scroll="alien" data-scroll-repeat="10" data-scroll-offset="100"> … </div>


Most of the time, when you build a transition or an animation on an element, you don’t need it to be played backward when this element goes outside of the viewport. That’s why I recommend to use these few lines of CSS:

[data-scroll].is-outside {
	transition: none;
	animation: none;


Custom prefix

You can change the prefix scroll in data-scroll and every attributes to prevent conflict with another JS library. To do so, add this attribute to your <html> element with your new prefix:

<html data-onscroll-effect-custom-prefix="my-prefix">

It will so be set to all attributes like data-my-prefix.

Asynchronous needs

For asynchronous needs, you can initiate the magic with:



You can also add some hooks: each element with data-scroll attribute fires an insideViewport event when it appears in viewport, and an outsideViewport event when it disappears from viewport. You can add event listeners on these events, and also test the state of the element with isRepeating, repeatCount and isInViewport properties. For example:

document.querySelector("#myElement").addEventListener("insideViewport", (event) => {
	console.log(`Is still repeating: ${event.target.isRepeating}`);
}, false);

Quick start


Then, add the script into your page, and it’s done.

With npm

Install with npm:

npm install onscroll-effect

Then load onScroll Effect into your application, inside your main JS file:

import "onscroll-effect";
// or

and the magic happens!


In addition of using ES5 version, compatibility for Internet Explorer is provided by polyfill.io which supports back to IE 7. And before you ask, yes, you can run it locally.