Accessibility & animation preferences

code updated:

I made all of the animations completely optional & improved the accessibility of this my site. here's how and why I did it.

first, flaming hot cheetos

I want to make a habit of sharing a song I like in every blog post.

this one is "Flaming hot cheetos" by Clairo

now: why did I make animations optional?

better question: why is it important to follow a visitor's animation preferences?

excessive animations on the web makes some visitors uncomfortable. in addition to being distracting or annoying for some people, animation can cause dizziness for people with vestibular disorders and motion sensitivity.

I never want to make someone feel uncomfortable with something I made, so I set out to make animations on my site completely optional by:

  • honoring prefers-reduced-motion
  • allowing immediate toggle on/off for animations at any time

checking user settings

prefers-reduce-motion setting allows someone to request that the system reduces non-essential motion and animation.

on macOS, you can set that in accessibility settings, under display. the setting is called "reduce motion".

screenshot of macOS Accessibility settings. the option Reduce Motion in the Display menu is checked

please refer to Mozilla's user preferences list for how to enable this setting on Windows and other operating systems.

honoring preferred-motion OS settings

I recommend this css tricks article about how to use the preferred motion media query, which allows you to check if someone set "reduce motion" at the OS level.

my usage looks like this:

@media (prefers-reduced-motion: reduce) {
background-image: url(STATIC-IMAGE-URL);
}

on my site, preferred motion OS settings take precedence. if you indicate prefers-reduced-motion: reduce, then I hide the "settings" menu with the animation options completely.

getting user preferences directly & immediately

as I mentioned, I have a "settings" menu in the top right of the page that has options for toggling animations on the entire site.

screenshot top right corner of the homepage of this site, showing 2 floating checkboxes with light purple background. the first checkbox is checked and reads 'animated backgrounds?' and the second is also checked and reads 'animated gifs?'.

reminder: this menu is hidden if you set the "reduce motion" preference on your OS.

when you change one of these checkboxes, your animation preferences are saved in your browser's localStorage with a little bit of javascript:

var bodyElem = document.querySelector("body");
var bgcheckbox = document.getElementById("animate-bgs");
var gifcheckbox = document.getElementById("animate-gifs");

function populateStorage() {
localStorage.setItem("animated-bg-pref", bgcheckbox.checked);
localStorage.setItem("animated-gif-pref", gifcheckbox.checked);
}

function setBgAnimationClass() {
var isAnimated = localStorage.getItem("animated-bg-pref");

if (isAnimated === "true") {
bodyElem.classList.remove("disallow-animated-bgs");
bgcheckbox.checked = true;
} else {
bodyElem.classList.add("disallow-animated-bgs");
bgcheckbox.checked = false;
}
}

function setGifAnimationClass() {
var isAnimated = localStorage.getItem("animated-gif-pref");

if (isAnimated === "true") {
bodyElem.classList.remove("disallow-animated-gifs");
gifcheckbox.checked = true;
} else {
bodyElem.classList.add("disallow-animated-gifs");
gifcheckbox.checked = false;
}
}

if (!localStorage.getItem("animated-bg-pref")) {
populateStorage();
}
if (!localStorage.getItem("animated-gif-pref")) {
populateStorage();
}

setBgAnimationClass();
setGifAnimationClass();

bgcheckbox.addEventListener("change", () => {
populateStorage();
setBgAnimationClass();
});

gifcheckbox.addEventListener("change", () => {
populateStorage();
setGifAnimationClass();
});

when either of those animation options are unchecked, I add a disallow-animated-bgs or disallow-animated-gifs, hide the animation, and show the static replacement:

.disallow-animated-gifs {
.animated-image {
display: none;
}

.static-image {
display: block;
}
}

I have set both "animated backgrounds?" and "animated gifs?" to be "checked" by default.

you can freely switch between different settings at any time. 💖