On scroll animations using waypoints.js and animate.css

On scroll animations using waypoints.js and animate.css

on July 31, 2014 in Tutorials

Did you ever wonder how the best themes implement on scroll animations? This tutorial will allow you to recreate the effect using the popular jquery-waypoints plugin as well as the animate.css library.

On scroll animation is a technique which has gained popularity over the past several months. It suits one-page websites as well as websites with many illustrations perfectly, giving them a more dynamic appearance. However, the animations can be applied to any element as we will soon see.
For this tutorial we assume the reader has some prior experience with javascript and more specifically with the jQuery library, as we will need the aid of the popular jQuery-waypoints plugin. Waypoints is a plugin that allows us to easily execute a function whenever we scroll to an element.
The following example will alert the user when he scrolls on any element that has a class ‘notify’:

$('.notify').waypoint(function(direction) {
  alert('Top of notify element hit top of viewport.');

One can pass a second argument to the waypoint function, which is an options object. An option of interest for us today is the offset option, which tells Waypoints how far from the top of the window the callback function should fire.

$('.notify').waypoint(function(direction) {
  alert('Top of notify element hit top of viewport.');

In the example above we express the offset as a percentage of the viewport’s height.
Having a solid grasp of how Waypoints work, we can now move on to Daniel Eden’s animate.css library. animate.css is a bunch of cool fun and cross-browser animations that we can use in our projects.
Grab a copy of the stylesheet and include it in your project. After that you will be able to animate your elements by simply adding the class animated to them, along with the name of the specific animation you want to apply.We will use jQuery to add the animation classes to our elements.The following code illustrates how this can be achieved:

$('.toBeAnimated').addClass('animated fadeInLeft');

The above code will make all elements that have a class toBeAnimated to animate
animate.css also let’s us modify the duration of our animations and add a delay which can come in handy.

.toBeAnimated {
  -vendor-animation-duration: 3s;
  -vendor-animation-delay: 2s;

The above style will trigger an animation that lasts 3 seconds, 2 seconds after the class animated is applied to an element.
The best way to define the animations (or behaviours in general) for an element would be through data attributes.We will use data attributes to specify what type of animations our elements will perform, as well as possible delays in the animation. Here is what the markup for an animated section will look like:

<section class="os-animation" data-os-animation="swing" data-os-animation-delay="0s">
  <h1>This section will swing</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

Studying the snipped above, one will notice that we added a class os-animation to our section. That will help us target this as well as other sections with the same class through jQuery. The two data attributes specify the animation we want the section to perform, as well as the delay (no delay in this case).
Wouldn’t it be great if our section was initially hidden and only appeared when it scrolled into view and animated? Let’s add some css that will help us accomplish exactly that:

  opacity: 0;
  opacity: 1;

It is now time to combine the two concepts we saw earlier and create a small script that will handle the animation of our elements once they come into view. Without further ado:

function onScrollInit( items, trigger ) {
  items.each( function() {
    var osElement = $(this),
    osAnimationClass = osElement.attr('data-os-animation'),
    osAnimationDelay = osElement.attr('data-os-animation-delay');
      '-webkit-animation-delay': osAnimationDelay,
      '-moz-animation-delay': osAnimationDelay,
      'animation-delay': osAnimationDelay
    var osTrigger = ( trigger ) ? trigger : osElement;
    osTrigger.waypoint(function() {
      triggerOnce: true,
      offset: '90%'

The above function expects two arguments, the second being optional. A list of items that we want to animate, and an optional container in case we want to perform staggered animations. For each of those elements, we extract the animation information from their data attributes, and animate them once they appear at the bottom of our viewport. Notice that we added the triggerOnce option in our options object since we want each element to animate only once, when it comes into our view as we scroll.
Calling the above function once the document has loaded with the following code:

onScrollInit( $('.os-animation') );

will animate our previous section as well as other sections with the same class and similar data attributes once they come into our view.
But what if I want staggered animations? An animation is called staggered when it contains a delay between each successive animation. You have most probably seen it in websites that animate paragraphs that belong in the same section in ‘layers’. Let’s see how we can use our previous function in order to achieve that as well. Create a section in your body of your html document that looks like this:

<section class="staggered-animation-container">
  <h1>This section contains staggered animations!</h1>
  <p class="staggered-animation" data-os-animation="fadeInRight" data-os-animation-delay="0.5s">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  <p class="staggered-animation" data-os-animation="fadeInRight" data-os-animation-delay="0.8s">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  <p class="staggered-animation" data-os-animation="fadeInRight" data-os-animation-delay="1.1s">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>

In the above code you will notice that we apply the animation attributes to the paragraphs inside the section, which all have the same class staggered-animation and we add a staggered-animation-container class to the section that contains them. The idea this time is to trigger the waypoint callback once the section is at the bottom of our view, and have the paragraphs inside animate in layers.Thus we will call our function this time like this:

onScrollInit( $('.staggered-animation'), $('.staggered-animation-container') );

This time we passed a second argument to the function as well. The first argument is the selector for the elements we want to animate, and the second is for their container that will trigger the animations once it scrolls into view. Notice in the markup that we needed different (incemental) delays for each item inside the container in order to achieve the effect.


  • langan
    langan - reply

    Nice article Roulis!

  • alexander
    alexander - reply

    a very cool post thx

    Damien - reply

    great info Thanks for the marvelous potisng! I genuinely enjoyed reading it, you’re a great author.I will remember to bookmark your blog and definitely will come back down the road. I want to encourage one to continue your great work, have a nice day!

  • Aaron O.
    Aaron O. - reply

    This is a great tutorial, and I used it on a few projects so far. The only modification I made was to add an onscroll event on window to trigger the onScrollInit() function. I did this because when the page loads, and if images, or other elements aren’t loaded, it throws off the offset and the animation loads before hitting the offset. So, before the onScrollInit function declaration, I added a variable called scrolling and set it to false. Then I wrapped the onScrollInit function in a on scroll event. If you need the animation to load like on a header, then it may be usefull to add another data-attribute to the animated element, something like data-animation-scroll=”false”, then use that conditional to control the window.on.scroll event.
    // Heres what I ended up doing
    var scrolling = false;
    function onScrollInit( items, trigger){
    // code from above
    $(window).on(‘scroll’, function(){
    onScrollInit( $(‘.os-animation’) );
    scrolling = true;

    Adrian M
    Adrian M - reply

    Great article and thanks Aaron for the input, helped me out bud!

    aneesa - reply

    can you send me a link to a preview?

    Melania - reply

    Very nice post. I just stumbled upon your wlebog and wanted to say that I’ve truly enjoyed browsing your blog posts. In any case I will be subscribing to your feed and I hope you write again very soon! Howdy!

    Fabio -

    Thanks for sharing. I will have to ttarslane the site from Japanese, but I like what they are doing. Looks like they have an unscannable animation intro, and then it rotates the same loop.I wonder if its automated like the other generators, or hand built?Looks like I have a lot to learn on this subject still.best,pd

    Mike - reply

    Great tip Aaron, I was stumped till you shed some light on it! Thanks man! Great article too by the way. I owe some of yall a beer!

  • Adam
    Adam - reply

    Good information on “On scroll animation technique”.Thanks!

    Panita - reply

    Ryan Lamont I blog frequently and I geulineny thank you for your information. The article has truly peaked my interest. I’m going to take a note of your site and keep checking for new details about once per week. I subscribed to your Feed too .

  • Subhasish
    Subhasish - reply

    Nice! Helped me out in my project , thanks a lot.

    Dimitrios Pantazis
    Dimitrios Pantazis - reply

    Glad you liked them!

  • Anja
    Anja - reply

    Exactly what I was looking for! THANKS!!!

  • Her
    Her - reply

    Great! But how can i make the animation repeats when scroll back, and not only for the first scrolling? Thanks!

    Harris Konstantourakis
    Harris Konstantourakis - reply

    You probably want to remove the “triggerOnce: true” option in your case!

    Her - reply

    I try this but notting happens!

  • Christian
    Christian - reply

    Nevermind.. I guess you need a different class for the trigger.

  • Pieter E.
    Pieter E. - reply

    I love this blog and solution. Thank you for explaining!
    I’d like to upgrade waypoints and animate.css to the latest versions. I tried the latest version of waypoints v4.0.0 (instead of v2.0.4) and animate.css v3.5.0 (instead of v3.1.0) on the code above. This doesn’t work, the animations aren’t triggered. Is there someone who tried the same and found already a solution? Thank you in advance for sharing. 🙂

  • sunil
    sunil - reply

    Thanks ! Great Article…..

  • Scott
    Scott - reply

    Your method is beautiful. Thank you for sharing.

  • Tim
    Tim - reply

    Great post, thanks for sharing. I have this working on my site, but if I have multiple trigger elements with the same class then they all fire when I reach the first one on the page instead of each firing as I scroll to them. I’ve tried adding an trigger.each(function() around the items.each(function() but haven’t had any success. Any thoughts?

    Harris Konstantourakis
    Harris Konstantourakis - reply

    Hi Tim,
    apologies for such a late reply, I am commenting on this in case others come across a similar issue. The second argument ( trigger ) in the function is to be used when one wants to ‘group’ animations.
    Your use case is different, you have some items that you want to animate once they come into view, and all the items have the same class. Let’s say that the class is ‘toBeAnimated’ .
    What you have to do is call onScrollInit( $(‘.toBeAnimated’) ); once. No second argument should be applied to the function.
    Hope that clears some things up!

  • dinh
    dinh - reply

    Thank god

    christos - reply

    Glad you liked it 😉

  • Kelyn
    Kelyn - reply

    Ohh Thank you so much! , I’ve been searching for something like that for days, it was implemented in my project and works perfectly. Thanks for sharing 🙂

  • VideoPortal
    VideoPortal - reply

    Nice tutorial. I am trying to animate a element so that when the element scrolls into view it s width grows from x to 1x and back to 1x. I have managed to get this to work using animation keyframes but the animation only works on page load is this possible to do?

  • zillo9w.com
    zillo9w.com - reply

    Simon Codrington explains how to use jQuery and CSS3 to add scroll-based animations to your site and thereby offer your users a more engaging experience.

  • Roee yossef
    Roee yossef - reply

    Thanks for the great solution.
    This works on one “staggered-animation-container”.. what if i need to use different triggers on different elements on the page?

  • Asher Garland
    Asher Garland - reply

    Building on the information above, I created a dead-simple way to create on-scroll animations for your elements. Check it out here: https://github.com/ashergarland/easy-waypoint-animate

    christos - reply

    Thanks for sharing!

Leave a reply

Your email address will not be published. Required fields are marked *