Florian Schroiff has been building for the web for almost 20 years. He has worked on countless accessible websites as a freelancer and for various agencies. As a front-end expert he is always searching for ways to improve accessibility and user experience and to share them with his team — and now with you!
Imagine you’ve just added a cool animation to your website – maybe a smooth transition between pages or a fun hover effect on your buttons. It looks great and adds that extra bit of flair you were after. But have you stopped to think about how all your users might experience it?
For many people, web animations can be more than just eye-catching – they can cause real problems. People with vestibular disorders might feel dizzy or nauseous when confronted with certain types of motion. Those with attention disorders might find animations distracting or confusing. Some users on the autism spectrum could struggle to process animated content. And for people with photosensitive epilepsy, flashing animations could even trigger seizures.
That’s why it’s so important to make sure your animations are accessible to everyone. It’s not just about ticking boxes for web accessibility laws (though that’s important too). It’s about creating a website that’s truly inclusive and user-friendly for all your visitors.
In this article, we’ll walk you through some key strategies for creating animations that are both engaging and accessible. We’ll look at how to comply with Web Content Accessibility Guidelines (WCAG) and, more importantly, how to make sure your animations enhance rather than hinder the user experience for everyone.
Essential WCAG success criteria for accessible web animations
When it comes to making your web animations accessible, there are three main WCAG success criteria you need to keep in mind:
- WCAG SC 2.2.2 Pause, Stop, Hide (Level A) – This criterion is all about giving users control over moving content. If you’ve got any animations that start automatically, last more than five seconds, and are shown alongside other content, you need to provide a way for users to pause, stop, or hide them. This rule applies to moving, blinking, or scrolling information.
For instance, if you’ve got an auto-updating stock ticker on your page, you should include pause and play buttons. This allows users who might find the movement distracting or difficult to read to control the animation.
- WCAG SC 2.3.1 Three Flashes or Below Threshold (Level A) – This guideline is crucial for preventing seizures. It states that web pages shouldn’t contain anything that flashes more than three times in any one-second period. If you do need to include flashing content, make sure it’s below the general flash and red flash thresholds.
- WCAG SC 2.3.3 Animation from Interactions (Level AAA) – This criterion focuses on animations triggered by user interactions. It states that these animations should be able to be disabled unless they’re essential to the functionality or information being conveyed.
For instance, if you have parallax scrolling effects on your site, you should provide a way for users to turn this off if they find it disorienting.
Designing engaging animations with accessibility in mind
It’s important to remember that creating animations that are both eye-catching and accessible shouldn’t limit your creativity. Quite the opposite: It challenges you to create great visuals that improve the experience for everyone.
Before we dive into specific WCAG recommendations, let’s remember a couple of key design principles that apply to accessible animations:
- If your animation conveys important information, make sure you’re providing that same info in a text-based format, too. This is where alternative text is crucial. For example, if you’ve got an animated infographic, you’d want to include a text description that covers all the key points.
- Pay attention to colour contrast in your animations, especially if they include text. Good colour contrast helps people with visual impairments read and understand your content more easily. This is particularly important for interactive elements like buttons or menu items.
By keeping these fundamentals in mind, you’re already on the right track to creating animations that work for everyone. But there’s more we can do to make our animations truly accessible. Let’s explore some specific strategies to take your animation accessibility to the next level.
Implementing user controls for WCAG-compliant animations
First things first: if you’ve got any animations that last longer than five seconds, you need to give users a way to control them. Why? Well, for some people, especially those with attention disorders, long or repetitive animations can be really distracting. And for users with vestibular disorders, certain types of motion can trigger dizziness, nausea, or even vertigo. Not ideal when you’re trying to browse a website!
So, what’s the solution? Play and pause buttons are your new best friends. These simple controls can make a world of difference to users who might otherwise struggle with your animated content.
Here’s a quick example of how you might add pause functionality to an animation:
<!-- Pause button -->
<button data-action="pause" aria-label="Pause Animation">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-hidden="true" focusable="false">
<rect x="5" y="4" width="4" height="16" fill="black"></rect>
<rect x="15" y="4" width="4" height="16" fill="black"></rect>
</svg>
</button>
And this is the play button:
<!-- Play button -->
<button data-action="start" aria-label="Start Animation">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" role="img" aria-hidden="true" focusable="false">
<polygon points="0,0 24,12 0,24" fill="black"></polygon>
</svg>
</button>
If your website’s default focus styles have been removed or need enhancement for better visibility during keyboard navigation, you can use the following CSS:
<!-- CSS to ensure keyboard focus is visible -->
<style>button:focus-visible { outline: 2px solid blue; /* Makes the focus state visible for keyboard navigation */} </style>
By using the :focus-visible
, the outline appears only when the button is focused via keyboard input, enhancing accessibility for users who rely on keyboard navigation without affecting mouse interactions.
To enhance the interactivity, you can implement a simple JavaScript toggle between the play and pause buttons like this:
// Select the buttons
const playButton = document.querySelector('button[data-action="play"]');
const pauseButton = document.querySelector('button[data-action="pause"]');
// Initially hide the pause button
pauseButton.style.display = 'none';
// When the play button is clicked
playButton.addEventListener('click', function () {
playButton.style.display = 'none'; // Hide play button
pauseButton.style.display = 'inline-block'; // Show pause button
// Add logic to start the animation
});
// When the pause button is clicked
pauseButton.addEventListener('click', function () {
pauseButton.style.display = 'none'; // Hide pause button
playButton.style.display = 'inline-block'; // Show play button
// Add logic to pause the animation
});
Designing for reduced motion: accommodating vestibular disorders
When we talk about accessible animations, we can’t overlook the needs of people with vestibular disorders. These folks might experience dizziness, nausea, or disorientation when confronted with certain types of motion on screen. It’s our job as web designers to make sure our snazzy animations don’t accidentally turn their browsing experience into a rollercoaster ride they didn’t sign up for.
So, how do we create animations that look great without making some of our users feel poorly? Here are some key strategies:
- First off, ask yourself: is this animation really necessary? Sometimes, the simplest solution is the best. If an animation doesn’t add real value to your site, consider leaving it out.
- If you do include animations, give users the power to turn them off. A simple toggle switch can make a world of difference. Use the ‘
prefers-reduced-motion
‘ media query. This nifty bit of CSS detects if a user has set a system-wide preference for reduced motion. Here’s how you might use it:
<button id="motionToggle" aria-pressed="false" onclick="toggleAnimations()">Disable Animations</button>
<script>
function toggleAnimations() {
const body = document.body;
const button = document.getElementById('motionToggle');
// Toggle the class for reduced motion
body.classList.toggle('reduce-motion');
// Update the button's aria-pressed attribute
const isReduced = body.classList.contains('reduce-motion');
button.setAttribute('aria-pressed', isReduced.toString());
// Dynamically update the button text based on the state
button.textContent = isReduced ? "Enable Animations" : "Disable Animations";
}
// Function to apply or remove reduced motion class based on preference
function applyReducedMotion(prefersReduced) {
const body = document.body;
const button = document.getElementById('motionToggle');
if (prefersReduced) {
body.classList.add('reduce-motion');
button.setAttribute('aria-pressed', 'true');
button.textContent = "Enable Animations";
} else {
body.classList.remove('reduce-motion');
button.setAttribute('aria-pressed', 'false');
button.textContent = "Disable Animations";
}
}
// MediaQueryList for prefers-reduced-motion
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
// Initial check
applyReducedMotion(mediaQuery.matches);
// Add an event listener to handle changes in the prefers-reduced-motion setting
mediaQuery.addEventListener('change', (event) => {
applyReducedMotion(event.matches);
});
</script>
<!-- CSS for reduced motion -->
<style>
/* In a real-world scenario, selectively disable only large animations */
.reduce-motion * {
animation: none !important;
transition: none !important;
}
button:focus-visible {
outline: 2px solid blue; /* Makes the focus state visible for keyboard navigation */
}
</style>
This snippet makes sure that:
- The button uses aria-pressed for accessibility, so screen readers know the current state of the button.
- The button text dynamically updates to reflect the current state of animations.
- The mediaQuery variable watches for changes in the user’s “Reduce Motion” preference. If the preference changes, the
applyReducedMotion
function updates the website’s animations accordingly.
⚠️ It’s important to note that this example is simplistic. In a real-world application, you would typically disable only large or obtrusive animations that might trigger vestibular disorders, not all animations. Subtle animations like a button fade-in are generally acceptable.
Managing flashing content and preventing seizures
Flashing content can be particularly risky when it comes to web animations. For some users, especially those with photosensitive epilepsy, rapidly flashing images or animations can trigger seizures. That’s why it’s crucial to handle this type of content with care.
The WCAG SC 2.3.1 Three Flashes or Below Threshold provides clear advice: avoid any content that flashes more than three times per second. It’s a simple rule that can prevent serious health risks for some of your users.
But what if your design really needs that flashing effect? Here’s what you can do:
- First, try to keep any flashing content below the three-flashes-per-second threshold. This alone can make your content much safer.
- If you must include faster-flashing content, keep it small. The WCAG suggests limiting the size to no more than 341 x 256 pixels.
- Always warn before any content is rapidly flashing. A simple alert can give users the chance to avoid content that might be harmful to them.
- Offer an alternative version of the content without the flashing effect. This ensures all users can access the information, regardless of their sensitivity to flashing images.
Here’s a quick example of how you might implement a warning and alternative:
<button id="flashingBtn">Show Flashing Animation</button>
<section id="warning" class="hidden" role="alert" tabindex="-1">
<p>Warning: This content contains rapid flashing that may cause discomfort or seizures in some individuals.</p>
<button id="safeVersionBtn" aria-label="View safe version of content without flashing effects">View Safe Version</button>
<button id="proceedBtn" aria-label="Proceed to content with flashing effects">Proceed</button>
</section>
<script>
document.getElementById('flashingBtn').addEventListener('click', function() {
document.getElementById('warning').classList.remove('hidden');
document.getElementById('warning').focus();
});
document.getElementById('safeVersionBtn').addEventListener('click', function() {
// Show the safe version of the content
});
document.getElementById('proceedBtn').addEventListener('click', function() {
// Proceed to flashing content, after adding confirmation or delay if needed
});
</script>
The button triggers the display of a warning section. Users are then given two options: to proceed to the content with flashing effects or to view a safe version. The event listeners for the buttons are placeholders and would need to be filled in with actual functionality.
Master accessible animation design with The A11Y Collective
We’ve covered a lot of ground in this guide, from implementing user controls to designing for reduced motion and managing flashing content. These strategies are key to creating animations that are not just visually appealing but accessible to all users, including those with vestibular disorders, attention disorders, and photosensitive epilepsy.
But this is just the tip of the iceberg regarding web accessibility. If you want to deepen your knowledge and skills in this area, The A11Y Collective is here to help. Our “Accessible design, the Basics” course covers animation accessibility along with a wide range of other essential accessible design principles. If you’re looking to improve other areas, like accessible content and coding, there’s a range of A11Y Collective courses available on these topics, as well.
Ready to take your web accessibility skills to the next level? Join us at The A11Y Collective and become a master of accessible animation design. Your future users will thank you for it!
Want to level up your accessibility skills?
Get started with our “Accessible design, the basics” course to learn the fundamentals of accessible website design. Make the web a more inclusive place for everyone!