search ]

Adding CSS Scroll Animations using AOS

You’ve probably encountered websites with various animations happening as you scroll down (On Scroll Animations). I’ll share with you a library called AOS (Animate On Scroll), which allows you to easily add these animations with full CSS control over them.

The concept behind AOS is quite simple: track all the elements and their positions according to the settings you provide, and then add or remove the aos-animate class that triggers the animation for the relevant element.

“Actually, it’s not as simple as it sounds,” notes the developer of the library, but the idea behind it is straightforward, and every aspect of animation is managed through CSS only.

How to Use the AOS Library

To start, you need to include the necessary files for AOS to work. Add the stylesheet file to the <head> of your page:

<link rel="stylesheet" href="https://unpkg.com/aos@2.3.4/dist/aos.css" />

Then, add the required script just before the closing </body> tag:

<script src="https://unpkg.com/aos@2.3.4/dist/aos.js"></script>

The examples above use aos@2.3.4, which is the latest stable release. You may see references to aos@next online – that points to a 3.0 beta that has been in development for years. Stick with 2.3.4 for production sites.

I won’t explain here how to add these in WordPress, as I’ve covered that extensively in previous posts with lots of examples. You’re welcome to take a look at the post on Adding CSS and JS to WordPress Sites. If you’re struggling, feel free to ask in the comments, and I promise to respond.

To save you time, you can download both relevant files from this link.

Initializing the AOS Library

To initialize the library, use the following code:

AOS.init();

AOS has several options, which I won’t expand upon here. The comments in the code provide excellent explanations.

Adding Animation to HTML Elements

Let’s take a look at an example of how to add animation to any HTML element. Assuming you’ve loaded the library correctly, adding animation to an element is done like this:

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

The result will be something like this (according to the CSS of that element):

Example Element

Or, for instance, the same example but with a longer animation duration:

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

The result:

Example Element

You probably understood that the attribute data-aos is responsible for the type of animation. Let’s change the animation for demonstration purposes:

<div class="some-item" data-aos="flip-left" data-aos-duration="1500">Example Element</div>

And here’s the result:

Example Element

You can also set a delay for elements using the data-aos-delay parameter. Here are three buttons with short delays between them:

<div class="buttons-aos">
    <button class="aos-button" data-aos="fade-up" data-aos-delay="0" data-aos-easing="ease-in-out">Button</button>
    <button class="aos-button" data-aos="fade-up" data-aos-delay="500" data-aos-easing="ease-in-out">Button</button>
    <button class="aos-button" data-aos="fade-up" data-aos-delay="1000" data-aos-easing="ease-in-out">Button</button>
</div>

Here’s how it looks:

Available Animations

AOS ships with a solid set of built-in animations you can use right away. Here are the main groups:

  • Fade: fade, fade-up, fade-down, fade-left, fade-right, fade-up-right, fade-up-left, fade-down-right, fade-down-left
  • Flip: flip-up, flip-down, flip-left, flip-right
  • Slide: slide-up, slide-down, slide-left, slide-right
  • Zoom: zoom-in, zoom-in-up, zoom-in-down, zoom-in-left, zoom-in-right, zoom-out, zoom-out-up, zoom-out-down, zoom-out-left, zoom-out-right

Each animation accepts parameters like data-aos-duration, data-aos-delay, data-aos-easing, and data-aos-offset to fine-tune the behavior.

AOS Configuration Options

When initializing AOS, you can pass a configuration object to control global behavior. Here is a full example with all available options:

AOS.init({
  // Global settings:
  disable: false, // accepts: 'phone', 'tablet', 'mobile', boolean, expression or function
  startEvent: 'DOMContentLoaded', // event that triggers AOS initialization
  initClassName: 'aos-init', // class applied after initialization
  animatedClassName: 'aos-animate', // class applied on animation
  useClassNames: false, // if true, adds data-aos value as classes on scroll
  disableMutationObserver: false, // disables automatic mutation detection (advanced)
  debounceDelay: 50, // debounce delay on window resize (advanced)
  throttleDelay: 99, // throttle delay on scroll (advanced)

  // Per-element settings (overridable via data-aos-* attributes):
  offset: 120, // offset (in px) from the trigger point
  delay: 0, // values from 0 to 3000, step 50ms
  duration: 400, // values from 0 to 3000, step 50ms
  easing: 'ease', // default easing for animations
  once: false, // whether animation runs only once while scrolling down
  mirror: false, // whether elements animate out while scrolling past them
  anchorPlacement: 'top-bottom', // which position of the element triggers the animation
});

A common setup for production is setting once: true so animations play once and don’t repeat every time the user scrolls back up. This feels less distracting and improves scrolling performance.

Adding Your Own Animation to AOS

If the animations provided by the library aren’t enough and you want to add your own animation to AOS, it’s quite simple since all animations are performed through CSS.

[data-aos="new-animation"] {
  opacity: 0;
  transition-property: transform, opacity;
}
[data-aos="new-animation"].aos-animate {
  opacity: 1;
}
@media screen and (min-width: 768px) {
  [data-aos="new-animation"] {
    transform: translateX(100px);
  }
  [data-aos="new-animation"].aos-animate {
    transform: translateX(0);
  }
}

You can then use this animation like this:

<div data-aos="new-animation"></div>

Accessibility Considerations

Scroll animations can be problematic for users who are sensitive to motion. Modern browsers support the prefers-reduced-motion media query, and you should respect it. AOS makes this easy with the disable option:

AOS.init({
  disable: window.matchMedia('(prefers-reduced-motion: reduce)').matches
});

This disables all AOS animations when the user has requested reduced motion in their operating system settings.

Native CSS Scroll-Driven Animations

It’s worth mentioning that browsers are rolling out native CSS scroll-driven animations through the animation-timeline property with scroll() and view() functions. This allows you to tie CSS animations to scroll progress without any JavaScript at all.

As of early 2026, Chrome, Edge, and Safari support this feature, but Firefox still has it disabled by default. For broad browser support, AOS remains a reliable choice. Keep an eye on animation-timeline as it matures – it may eventually replace JavaScript-based scroll animation libraries entirely.

FAQs

Common questions about AOS and scroll animations:

Is AOS still maintained?
AOS is a mature, stable library. The latest stable release is version 2.3.4. While active feature development has slowed, the library works reliably and continues to be widely used in production. A 3.0 beta (aos@next) has been in development but has not reached a stable release.
Does AOS affect page performance?
AOS is lightweight at around 8KB. However, animating many elements at once can cause layout recalculations and affect scrolling smoothness. Use the once: true option so animations run only once, and avoid animating dozens of elements on the same page.
Can I use AOS with React, Vue, or other frameworks?
Yes. Import AOS in your component, call AOS.init() in the mounted or useEffect hook, and add data-aos attributes to your JSX or template elements. If the DOM changes dynamically, call AOS.refresh() after updates so AOS picks up the new elements.
How do I respect the prefers-reduced-motion setting with AOS?
Pass a function or expression to the disable option. For example: AOS.init({ disable: window.matchMedia('(prefers-reduced-motion: reduce)').matches }). This turns off all scroll animations when the user has enabled reduced motion in their OS settings.
What is the difference between once and mirror in AOS?
The once option controls whether the animation plays only on the first scroll-down. When set to true, the element animates in once and stays visible. The mirror option controls whether elements animate out (reverse) when you scroll past them. By default both are false, so animations replay every time the element enters the viewport.
Can I create custom animations with AOS?
Yes. Define a CSS rule targeting [data-aos="your-animation-name"] with the initial state, and another rule for [data-aos="your-animation-name"].aos-animate with the final state. Then use data-aos="your-animation-name" on any element. Since all animations are CSS-based, you have full control over transforms, opacity, and transitions.

Summary

AOS is a lightweight, CSS-driven library that makes adding scroll animations straightforward. Set the data-aos attribute on any element, initialize the library, and you’re done. For production, pin to version 2.3.4, set once: true for a cleaner experience, and remember to disable animations for users who prefer reduced motion.

You can find more information about the library’s options, available animations, and all parameters on the AOS GitHub page.

Join the Discussion
0 Comments  ]

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo