8/22/2021

Animatorsmooth Animations On Scroll

30
  1. Scroll animations AOS (Animate On Scroll) allows you to animate elements as you scroll down, and up. If you scroll back to the top, elements will animate to their previous state and are ready to.
  2. By default, the animations are replayed every time the elements scroll into view. You can set the value of this attribute to false in order to animate the elements only once. Below is an example.

AWS Amplify - the fastest, easiest way to develop mobile and web apps that scale.

Bug 204882 - Add support for scroll behavior relies on ScrollAnimation of the Web process. Most useful premiere hotkeysfasrmen. Scroll-animation-in-web-process-for-review (98.20 KB, patch).

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:

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

or with a different transition duration:

**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.

Animatorsmooth Animations On Scroll

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.

May 19, 2019

It’s time to add some animation to our page when a visitor scrolls. For this tutorial I’ve set up a demo page all about pizza. We’ll use this to learn how to have animations triggered by scrolling, and investigate ways we can do so efficiently.

In this tutorial we’ll learn how to make use of the requestAnimationFrame as well as Intersection Observer methods to detect when elements are within the viewport of the browser. We’ll introduce a new will-change property and use that to make sure our animations are smooth, and we’ll put these together with some transitions to create animations that are triggered on scroll.

Note: The video doesn’t include the Intersection Observer approach but you’ll find it in the code below.


You’ll find the HTML and CSS you need to get started in this sample code file. Look for folder 01-start. A completed version of this tutorial’s code is in the folder 01-end.

Starting HTML

In the index.html file you’ll find a couple of page sections. The first is a header that contains the main photo and heading text.

Beneath this we have a longer article. It’s made up of paragraphs and images. I’ve added the class inline-photo to each of these images. We’ll use this class to style the images, as well as animate them.

Let’s see how it looks. We can see the images and the text, but no animation yet.

Showing on scroll

For this tutorial we’ll be using some JavaScript. The idea is to check, as the page is scrolled, for any special elements we want to animate. If any of these special elements are visible, we can give them a special class and use CSS to animate or transition them into view.

To do this we’ll need two things. We’ll need the JavaScript to detect and add a class when one of these elements is visible, and we’ll need to set up before and after styles on the elements.

JavaScript

Let’s begin with our JavaScript. At the end of the HTML file you’ll find a reference to the JavaScript file show-on-scroll.js. This is in the javascripts folder.

Animatorsmooth Animations On Scroll Backgrounds

In our editor we’ll open this file. It’s blank for now. This is where we’ll set up the code to detect scrolling and check for those elements we want to show.

We won’t be using jQuery for this one. Instead we’re going to use a handy method built in to browsers called requestAnimationFrame.

Back in the day when building something like this I’d have used the scroll browser event, and then checked the state of the page while scrolling.

This might work in some ways, but sadly this has a couple of big problems. The first being efficiency. When scrolling, the console.log here will fire like crazy. If we’re doing anything like parsing the DOM tree or other heavy tasks, this will add a lot of overhead to the browser. It could very easily slow things down and make our animations janky.

A second issue is iOS. Scrolling on some phones only results in this scroll trigger being fired after the scrolling has finished. We’d like this to work on mobile, so that’s a big fail there.

Thankfully requestAnimationFrame solves these issues. It’s a method that we can use to repeatedly check our page to see if elements are visible, while making sure we don’t overload the browser by checking thousands of times per second. It does this by limiting how often the callback is executed to either the screen’s refresh rate or 60 times per second.

60 times per second might sound like a lot but for the work we’ll be doing it’s very slow and won’t overload the browser.

To set up our requestAnimationFrame method we’ll apply it to a variable. This way we are able to have a fallback function for browsers that don’t yet support it.

Here we’re saying that scroll should be the window.requestAnimationFrame method, or (if this isn’t available), use this simple function that waits one-sixtieth of a second before calling the callback.

Next we’ll grab the elements on the page we want to look out for.

This will look for all elements with class show-on-scroll and return them as an array we can loop through.

Let’s set up that looping function.

We begin by setting up the function loop. This is a function we want to loop through all the elements and check if they’re visible. We do this using the forEach method. For each of the show-on-scroll elements found this loop will check if it’s in the viewport, and if so, add the class is-visible. Otherwise it’ll remove the class.

Lastly we want to keep firing this function so we’ll make use of our requestAnimationFrame helper we set up earlier, and pass this function as a callback.

This means that as soon as requestAnimationFrame allows us, it’ll repeat this function and update classes as needed.

As it stands, this won’t do much yet. We need to kick it off by calling the loop function.

Checking if in the viewport

There’s one bit missing. In the loop function we’re calling a method isElementInViewport. Unfortunately this isn’t a browser method, we’ll have to write that one ourselves. Here’s a handy one I grabbed from Stack Overflow.

Just to run through this quickly. It begins by checking to see if jQuery is defined. jQuery changes the way elements are made available and this corrects for a possible issue that might arise. Next it uses a handy method called getBoundingClientRect. This is the rectangle around the element we want to check.

Next it does a series of checks that will return true if the element is on the page and on the screen.

Alternate approach: Intersection Observer

The above works pretty well, but there’s a newer way to approach this problem using the browser’s Intersection Observer API. This is quite well supported in browsers, with the exception of Internet Explorer (currently IE11 does not support this, so will need a polyfill).

The Intersection Observer looks at the target element’s position in relation to a root element, and when they “intersect”, will return true. In this case we can use it to tell us when our show-on-scroll elements are within the viewport.

When setting up an instance of IntersectionObserver we can pass in options such as the root element want, or even the “margin” by which the elements need to overlap. For now though I’ll keep it simpler and just use the defaults. See the docs for more details.

We can replace the above JavaScript with this:

To step through this - it’s first setting up a callback function that will be called every time one of our observed targets enters or leaves the viewport.

We then instantiate the observer using this callback function. With those two pieces put together, we then grab all our targets, and loop through them, attaching a listener (observe) to each one. When the element enters or leaves the viewport, it’ll run the callback function.

Lastly, this callback function toggles the class is-visible on our element. This approach is simpler that the previous JavaScript but do keep in mind that it might not work so well in Internet Explorer currently. Check the CanIUse page for more info.

Let’s save this and set up our HTML to make use of this new power.

Selecting the elements

While there’s a bit going on there in the JavaScript, the result is quite simple. It’s going to apply an is-visible class when selected elements show on the screen. Let’s choose which elements we want to show.

In our index.html file we start by adding the class show-on-scroll to each of the photos.

Lastly we’ll also add this class to the header of the page. It’ll be nice to have an animation on the titles and since this is just adding a class, we can totally do that in CSS.

In our browser we can now test this. Opening the inspector we should see the is-visible class appearing and disappearing as we scroll.

Time to use this for some animation!

Animating the photos

In the scroll.css file in the stylesheets folder we find some initial styles for the photos. Let’s set these up to be animated by making a few changes.

We want these to fade in so we set the opacity to zero. Then we also want these photos to slide into place, so let’s adjust the transform to translate them down 4em, and give them a few degrees more rotation.

Next we set up the transition we want to happen when these photos become visible. We add a transition for the transform, with a duration of 4 seconds, a quarter-second delay and the exponential ease-out timing function. We also fade it in using the opacity property, making it a little quicker than the transform.

We’re using a delay so that if our visitor is scrolling slowly, the animation won’t have finished before the photo is properly visible on screen. It’s a small tweak helps the flow of the page.

Lastly we add a property we’ve not used yet, the will-change property. This is a way of telling the browser to prepare to animate the element. We supply this property the values transform and opacity.

With this done, the photos will be invisible. We need to add some CSS to make them visible.

We add a new rule for the is-visible classed elements. In this we make them visible with opacity of 1, and we set the transform to just a slight rotation.

Here’s how it looks, showing the images as we scroll down the page.

Animating the header

Scroll

So far so good! Let’s make use of the same JavaScript to bring animation to the header.

Earlier we added the show-on-scroll class to the header. We can make use of the is-visible class to animate this part too. We’ll need to set up a couple of different animations. First we’ll have it fade in, then the main photo will pop into place and the text will slide up into place beneath it.

Since we’re doing this by applying a class, we have a situation where there’s a change from one state to another. When we change from one state to another it’s a good opportunity to use transitions, but if we wanted to do something more advanced here we could also use keyframes and animations.

For now though we’ll get by with a couple of transitions. Whenever possible I like to try to use the simplest approach before jumping into more complex solutions.

We begin by fading in the header.

We create a header style block and set the opacity to 0, as well as add a transition for the opacity.

Next the header is given an opacity of 1 when the is-visible class is applied.

For the header image and title we’d like to scale the photo and push the text down a bit. We can add styles to do this.

This sets up the initial states of the elements. The photo is scaled down to .8 of it’s normal size. The heading text is pushed down 1em. I’m using absolute positioning on this title text, setting the left and top to 50% of the header. This transform corrects by pulling the text back into the center and then adding an extra 1em to push it down a bit.

The next step is to add the styles for when the header has the is-visible class.

We start with is-visible then main-photo to specify the photo when it’s parent has the is-visible class. In this state we can remove the transform. For the heading text we want to position it in the center of the screen.

With the two states defined the last thing it to add a transition.

We specify both the main-photo and the heading. For each of these we apply a transition to the transform property, with a long duration of 4 seconds, a delay as before, and the exponential ease-out timing function.

We’ll also add a will-change property here to tell the browser to optimise the transform property on these elements for animating.

Let’s see it in action.

Animatorsmooth Animations On Scroll Fonts

Here we see that on load, the header fades in and the photo and text transition into place. If we scroll the page we see each of the photos fading in as they enter the viewport.

What we learned

In this tutorial we were introduced to the handy requestAnimationFrame method. We wrote a handy JavaScript utility to detect when an element is inside the viewport, and apply a class to it. We will be able to use this any time we want to trigger animations on an element on scroll.

We also made use of the will-change property, which allows us to hint to the browser which properties are going to be animated.

Level up your CSS animation skills!

If you like this, you’ll love my video course on CSS animation. As a fan of this site you can save over 90% on the course today.

Animatorsmooth Animations On Scroll Cursor

Save over 90% and Level Up Your CSS Animation Skills today!