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.
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.
I wanted to split the responsibilities with my new library:
This allows you to add your own animations easily, and do things like change them according to the viewport.
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.
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:
aoswith the name of your animation
transition-property(by default this is
all, so it’s more performant and more predictable if you narrow the transition to the intended properties)
Things like duration/delay/easing are set independently of the animation.
or with a different transition duration:
**Tip:** You can use
data-aos instead of
aos to make your HTML validate properly.
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.
tabletor with a custom condition/function
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
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.
show-on-scroll.js. This is in the
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
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.
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
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.
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.
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 toggles the class
Let’s save this and set up our HTML to make use of this new power.
is-visible class when selected elements show on the screen. Let’s choose which elements we want to show.
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!
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
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.
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
We create a
header style block and set the
opacity to 0, as well as add a transition for the opacity.
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
top to 50% of the
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
We start with
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.
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.
In this tutorial we were introduced to the handy
We also made use of the
will-change property, which allows us to hint to the browser which properties are going to be animated.
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.
Save over 90% and Level Up Your CSS Animation Skills today!