AOS: CSS-Driven “On Scroll” Animation Library

Avatar of Michał Sajnóg
Michał Sajnóg on (Updated on )

The following is a guest post by Michał Sajnóg, a front end developer at Netguru. Michał has created one of those “when you scroll to here, trigger this animation” libraries. One of the things I like about it is that it leaves as much as it can to CSS for creating and controlling the animation themselves. Not to mention it’s proved itself by working well on a number of production sites. I’ll let Michał walk you through it.

Have you ever seen those long web pages where different animations are being applied as you scroll down? I’d like to share with you a plugin I wrote that makes it really easy to handle all kinds of animations with full CSS control and no pain.

If you’d like to get right into it, the code is on GitHub.

The Problem With Other Libraries

In my previous company we were using WOW.js (or other similar libraries) to animate elements on scroll. For simple projects it was quite nice, but on larger sites we wanted to have more control over what’s actually happening. In all of popular libraries, animations were completely handled by JavaScript by inserting inline CSS. Arghgh! Inline styles are evil. They are hard to control and override. Though, in some cases it’s ok to set them using JavaScript, it’s still much cleaner to just leave them where they belong and handle all CSS related things inside CSS file.

I decided to create a library that has a pure goal – detect position of elements and then add appropriate classes when they appear in viewport.

Controlling Animations Entirely in CSS

I wanted to split the responsibilities with my new library:

  • Have all the logic inside the JavaScript
  • Have all the animations in the CSS

This allows you to add your own animations easily, and do things like change them according to the viewport.

How AOS Works

The idea behind AOS is straightforward: watch all elements and their positions based on settings you provide them. Then add/remove the class aos-animate. Of course, in practice, it’s not always that easy, but the idea behind AOS is as simple as that. Every aspect of animation is handled by CSS.

Example Animations in CSS

The are lots of different animations ready to use out of the box, but creating new ones is simple also. Here’s an example:

[aos="fade"] {
  opacity: 0;
  transition-property: opacity;

[aos="fade"].aos-animate {
  opacity: 1;

You don’t have to worry about duration or delay. In the CSS, you only:

  • add styles for the attribute aos with the name of your animation
  • set the transition-property (by default this is all, so it’s more performant and more predictable if you narrow the transition to the intended properties)
  • add the post-transition properties on .aos-animate

Things like duration/delay/easing are set independently of the animation.

Example HTML

<div class="some-item" aos="fade">Example Element</div>

or with a different transition duration:

<div class="some-item" aos="fade" aos-duration="500">Example Element</div>

**Tip:** You can use data-aos instead of aos to make your HTML validate properly.

Live Demos

With different animations:

See the Pen AOS – animations by Snik (@michalsnik) on CodePen.

With anchor setting in use:

See the Pen AOS – anchor by Snik (@michalsnik) on CodePen.

With anchor placement and different easing:

See the Pen AOS – anchor & anchor-placement by Snik (@michalsnik) on CodePen.

With simple custom animations:

See the Pen AOS – custom animations by Snik (@michalsnik) on CodePen.

Additional Features

  • anchor – Animate one element based on position of other element
  • anchor placement – Animate an element based on it’s position on the screen. It doesn’t have to animate only when it appears in viewport, but for example when bottom part of it hits middle of the screen
  • both way animations – By default elements animate while you scroll up and down, but you can force it to animate only once
  • easy disabling – Disable animations on mobile devices using predefined options like mobile, phone, tablet or with a custom condition/function
  • async aware – Recalculates positions of elements on DOM changes, so after loading something using Ajax, you don’t have to worry about anything (unless you support IE9, because it needs mutation observer)
  • no dependencies – This library is written in pure JS and doesn’t rely on any dependencies

AOS is fully open source, so if you have an interesting idea or something is not working how you’d expect open issue and see you on GitHub! Any contribution is highly appreciated.