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 isall
, 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.
This plugin seems so easy to use, I am very happy to discover it!
Glad to hear that :)
I can’t seem to get this working for some reason. I’m working of the CDN versions and following the git set up instructions, and nothing works for me. Any ideas where I could be going wrong?
I like all the default animations it ships with, but i still prefer jlmakes’ 3,3 KiB scrollreveal.js: https://github.com/jlmakes/scrollreveal.js
Scroll Reveal is also a great library – no doubts. AOS provides similar features, but in a slightly different way and gives you more control over animations.
The latest version of Chrome (51) includes a new API called “IntersectionObserver”, which handles detecting when elements come into (“intersect” the) view.
It is only available in Chrome for now, but since Chrome is the most popular browser, and because most users are very quickly updated to the latest version within a short period of time, it’s already very much “in the wild.”
Thanks for your input. It’s really nice and very promising feature, but I’m willing to support more browsers so I’d rather leave it as is for now, it has been tested and seems to be working fine across different browsers.
This plugin its awesome! I wonder if it is better to have the feature that makes the effect just once while?
This plugin its awesome! I wonder if it is better to have the feature that makes the effect just once?**
Thanks! You can set once option while initializing AOS or set aos-once=”true” on a specific element and it will animate only once then :)
@pmeriton Thanks! You can set
once
option while initializing AOS or setaos-once="true"
on a specific element and it will animate only once then :)@Ben it’s really nice feature, but I’m willing to support more browsers so I’d rather leave it this way for now.
If you care about HTML5 validity (Google does…) you should prefix all custom attributes with “data-“.
Hi Phil, you can use either
aos
ordata-aos
, both versions work. My friend added this feature to AOS some time ago.Well then educate correct HTML and use the version with “data-” prefix. If you ask me the other one should not even exist.
If I use data-aos (instead of just aos) on elements that are already visible on load those elements won’t get animated. Feels like a small bug.
@Moo I’ll consider this, but this would be a major change as it’ll break up the backwards compatibility.
@toni it sounds like a bug indeed. If you find something – feel free to contribute and add issue on github :) Then it’ll be much easier to follow further changes and existing problems.
Hey this one a great library,
Can this library be used to create parallax image scrolling? Any example?
Unfortunately no, this plugin doesn’t serves this purpose. However if you insist you can set some anchors on background elements and trigger certain animation like transform using longer duration and therefore achieve sort of parallax effect, but it’s probably not the best solution.
For parallax you can try https://dixonandmoe.com/rellax/ It looks like an interesting library and may be something that suits your needs :)
This is great, thank you! I’ve been using ScrollReveal for awhile and have been looking for a smooth, simple replacement. This may just be it.
One feature that ScrollReveal has that would be a great addition here is distance- how far an item travels from A to B during its animation. Would love to have that added if possible.
Look forward to using it!
Thanks @Daniel, I’m glad you like it.
It’s an interesting feature, I’d be happy to discuss about it on github. Feel free to add an issue if you have an idea, it’s always good to see what other people have to say about possible features as well :)
Holy Sh*t… I’m actually making a site that need animation on scroll with visible effects. Nice!
Checked the demo http://michalsnik.github.io/aos/ on a desktop screen and things work nice if they are supposed to work the way they work. Not entirely sure I am getting the full spiel here since I tested this in FF 28.
Would it make sense to mix this with Velocity.js at all? I mean having the animations being smoothed out just a tiny notch by swapping the easing functions with Velocity. Does that make sense at all?
Another thing that caught my eye. When I resize the browser to a smartphone size width the animations are almost always only visible towards the top of the viewport.
When I scroll down to the “Zoom” section there is no animation in the narrow view whatsoever. Perhaps making the demo responsive, i.e. on a narrow viewport (portrait smartphone) have one single column of animations that can be nicely seen in the middle of the column instead of what you have now would be something to make the demo even more awesome, what do you think? Like this users can check how well this works on mobile, something I find important these days.
Congrats on the great work otherwise. Currently working a one-page layout for a client and this might come in very handy.
Thank you.
Hi, you’re absolutely right. I have to work on this demo and make it responsive, hopefully I find some time over the weekend :)
There is a chance you encountered some problems while resizing window, as there was an issue that I fixed today and it should work better now.
Speaking of Velocity.js – it’s rather not the way I’d like to go with this library. Whole animation part is handled in CSS so moving easings to JavaScript is just the oppsite of what I wanted to achieve with this library. Hope you get my point of view :)
However recently idea came out to add support for Animate.css library, and it’s something I’m going to think about.
Have fun and see you on github!
Nice stuff, This is just what I needed.
Waaaa! I was looking for that! WoW is great but à little bit to simple … I used to work with superscrollorama .. but to complex and deprecied..
thank’a lot I will use it definitevly! great work !
Thanks John, I really appreciate it :)
Nice work. We’ve been using wow.js for a bit but it always felt a bit unsavory to inject the style rules inline. I just took a quick peek at the source JS on GitHub — do you think using hardware acceleration or the
will-change
property might help? Reference: https://dev.opera.com/articles/css-will-change-property/Hi Bob, thanks for pointing this out. Though, I already have this on my roadmap and I’m going to give it a shot very soon and see if it actually improves performance in modern browsers in this case. Stay tuned
Great resource, I already implemented it on one of my newest projects and it feels great. I have faced some kind of annoying bug though. On mobile devices the animations are causing overflow-x to appear thus creating a white gap on the right. Is there some some way I can disable animations specifically on mobile devices?
Thanks in advance.
Hey,
Thanks! You could set
overflow-x: hidden
onbody
and this should fix this issue.However if you’d like to disable this plugin on mobile device you can set
disable
setting on init, like so:mobile
– disable AOS on tablets and phonesphone
– disable AOS on phonestablet
– disable AOS on tabletYou can also instead of one of the predefined strings use some variable or even pass there your own function :)
I hope you find this helpful!
Hi!
I really love your plugin, it’s super easy and super usable. I’ve only one question: is there any way to set the length of the movement of the elements during the fade?
Thanks a lot!
Nice work! Thanks :)
Looks great Michal, I’m excited to try it out in some new projects. Thank you!
I’m pleased to have discovered this library. Thank you for making it available. Question: Could one utilize this library in WordPress, perchance? If so, do you have any recommendations or tips?
Thank you kindly in advance.