We want to add some visual appeal to some of our content via scroll animations; IE have the content fade or slide in as the user scrolls down the page. The primary Library we're looking at using for this is AOS

Wondering though: are we shooting ourselves in the feet by using these? Most of these libraries seem to require our content to be hidden by default. I can't imagine this is great for SEO or accessibility. I also know of a Safari limitation where hitting the back button will load whatever state the page was last in and further js will not fire.

Does anyone have thoughts on the use of these libraries in general, if there are any shining stars among them (perhaps where content doesn't START hidden, but is done by js), or if there are best practices for avoiding any of the potential drawbacks?

Thanks for any insights!

1 Answer 1


The one thing to consider with the fade in animations from an accessibility perspective is people with vestibular disorders (sensitivity to motion causing nausea etc.).

If you do not account for this your site would fail under WCAG 2.3.3 Animation from Interactions (albeit it is a triple AAA criteria)

However there is a technique you can use to fix this using prefers-reduced-motion media query.

All you would do is use that media query to disable all animations on the page that are non-essential.

Ideally you would also have a setting screen somewhere that allows users to switch animations off. I normally put all accessibility stuff under a menu item "accessibility settings" if you are able to do the same I would.

A rough idea of how to handle it with AOS

Now with the AOS library mentioned you do have the issue that the styles are already added to the page, so even if we disable AOS (by not initialising it) we still have the issue of hidden items.

One option here would be to remove the stylesheet if AOS is not going to be initialised. However this has a big problem, if your JavaScript fails a lot of items on the page will be hidden.

Instead we reverse the process, check if the user is happy to see animations and if they are we dynamically insert the AOS JavaScript and CSS file into the page.

This is exactly what I do below in the example.

Hopefully the above explanation and demo below give you a good starting point.


Please note the below example is not complete as you will still get a flash of the original page before AOS is added. If you have a loader / spinner this isn't an issue but if performance is important (and it is) you would need to roll your own implementation (which is beyond the scope of a stack overflow answer!).

Quick way to test - in Developer Tools (F12) press Ctrl + Shift + p and search for "prefers". Look for the option "Emulate CSS prefers-reduced-motion: reduce" and toggle that on. Repeat that process to turn it off.

var hasAlreadyBeenAdded = 0;

//function used to add the CSS and JS and initialise AOS
function addAndInit(){
// check that we haven't already added the script and css, although probably not necessary.
if(hasAlreadyBeenAdded == 0){

//add the script
var aosScript = document.createElement('script');
aosScript.setAttribute('src','https://unpkg.com/[email protected]/dist/aos.js');

//add the CSS
  var aosLink = document.createElement("link");
  aosLink.type = "text/css";
  aosLink.rel = "stylesheet";
  aosLink.href = "https://unpkg.com/[email protected]/dist/aos.css";
//init AOS
aosScript.addEventListener('load', function() {
      duration: 1200,

  //set the flag that the item has already been added to avoid adding it again
  hasAlreadyBeenAdded = 1;

const reducedMQ = window.matchMedia("(prefers-reduced-motion: reduce)");

// Check if the media query matches or is not available.
if (!reducedMQ.matches) {
  //user has not indicated wanting reduced motion so init the library

// Adds an event listener to check for changes in the media query.
reducedMQ.addEventListener("change", () => {
  if (!reducedMQ.matches) {
    //user has changed their preference to not wanting reduced motion so init the library
    // this seems to work to disable AOS once it is active, bit of a hack but as not familiar with the library it will have to do.
  disable: function() {
    return true;
* {
  box-sizing: border-box;

.item {
  width: 200px;
  height: 200px;
  margin: 50px auto;
  padding-top: 75px;
  background: #ccc;
  text-align: center;
  color: #FFF;
  font-size: 3em;
<div class="item" data-aos="fade-up">1</div>
<div class="item" data-aos="fade-down">2</div>
<div class="item" data-aos="fade-right">3</div>
<div class="item" data-aos="fade-left">4</div>

<div class="item" data-aos="zoom-in">5</div>
<div class="item" data-aos="zoom-out">6</div>

<div class="item" data-aos="slide-up">7</div>

<div class="item" data-aos="flip-up">8</div>
<div class="item" data-aos="flip-down">9</div>
<div class="item" data-aos="flip-right">10</div>
<div class="item" data-aos="flip-left">11</div>

p.s. Stack Overflow isn't the place to talk about SEO as that would cause plagues, famine and destruction apparently (only kidding, but people have a real thing about SEO here so be careful when using that tag), but just so you are aware as long as you implement the animations correctly it won't affect SEO in any way other than if the page load performance is affected (or you introduce Cumulative Layout Shifts and it affects your Web Vitals etc.).

Whether it will adversely affect your conversion rates and site usability is another question entirely so you would have to keep an eye on that (spoilers: it probably will affect conversion rates adversely, but only a small amount, so I generally wouldn't recommend it if this is a sales site and conversions are important.).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.