Animation
Any kind of moving, blinking or auto-updating content displayed on a webpage can be referred to as animation. This type of content is used to display information or enhance the aesthetic appeal of a webpage thereby attracting users’ attention.
However, this type of content can cause difficulties for users with visual or cognitive disabilities.
NOTE:
- New to accessibility or uncertain of requirements, it will be helpful to review all sections below.
- Already familiar with requirements, skip to the “Working Example” section for sample HTML, CSS and JavaScript (when needed), along with a working demo.
- Animation that starts automatically, plays for more than 5 seconds, can cause accessibility barriers. Hence, there SHOULD be a mechanism to pause, stop or hide the animation. This helps users to play it according to their convenience/needs.
- When a user pauses and plays content again, ENSURE that the animation continues from where it was paused.
-
An accessible name MUST be defined for the image button. For more information on
making the Image Button accessible, refer to the Images component.
- For color contrast requirements for an image button, refer to the Color component.
- Blinking content if used, SHOULD have a mechanism to stop the effect, or it SHOULD stop after a short time (e.g., after 5 seconds)
-
Flashing content if used, SHOULD NOT have more than 3 flashes per second, and it
SHOULD also stop after a short time.
Note: Flashing content is when there are more than 3 flashes per second. Whereas blinking content will generally have flashes that are below the threshold. -
An alternative way to handle animation would be to use CSS media query
prefers-reduced-motion
. This will allow users to view content based on their device’s display setting – Animation/Reduce motion. More information about the media query can be found at https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion
Note: The option to control animation is supported by all the major devices today. - For color contrast requirements in animations, refer to Color component.
- For complex animations, an alternative description SHOULD be provided. Refer to the Images component for handling textual description for non-text content.
- If the animation includes spoken content, provide a transcript for people who are deaf or hard of hearing.
- If there is spoken dialogue in the animation, include captions that are synchronized with the audio.
Animations that are implemented correctly majorly benefit the below users.
- People with cognitive disabilities
- People with visual disabilities
- In certain situations, also benefited for people with hearing impairments.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
<div class="carousel" role="region" aria-label="Featured Articles Carousel">
<div class="carousel-controls">
<button type="button" class="toggle-button" aria-label="Pause slides"><svg viewBox="0 0 512 512" width="32" class="play-pause" aria-hidden="true">
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"/>
</svg></button>
</div>
<button type="button" class="previous fas fa-chevron-left" aria-label="Previous Slide"></button>
<div class="slides" aria-live="off">
<div class="slide" aria-hidden="false" role="group" aria-label="slide 1 of 4">
<div class="card reorder">
<h2>MyLab</h2>
<img src="/resources/developers-corner/reference-library/common-images/smiling-girl-working-with-laptop.jpeg" alt loading="lazy" width="400" height="200">
<p>Data-driven guidance to help improve results with engaging, interactive content by expert authors.
<a href="#">Explore MyLab</a>
</p>
</div>
</div>
<div class="slide" aria-hidden="true" role="group" aria-label="slide 2 of 4">
<div class="card reorder">
<h2>Mastering</h2>
<img src="/resources/developers-corner/reference-library/common-images/woman-working-with-laptop-on-couch.jpg" alt loading="lazy" width="400" height="200">
<p>Tools to help create immersive science & engineering courses that increase engagement.
<a href="#" tabindex="-1">Explore Mastering</a>
</p>
</div>
</div>
<div class="slide" aria-hidden="true" role="group" aria-label="slide 3 of 4">
<div class="card reorder">
<h2>Revel</h2>
<img src="/resources/developers-corner/reference-library/common-images/woman-with-headphones.jpeg" alt loading="lazy" width="400" height="200">
<p>A dynamic mobile reading experience that blends digital text and media to bring concepts to life.
<a href="#" tabindex="-1">Explore Revel</a>
</p>
</div>
</div>
<div class="slide" aria-hidden="true" role="group" aria-label="slide 4 of 4">
<div class="card reorder">
<h2>eTextbooks and Pearson+</h2>
<img src="/resources/developers-corner/reference-library/common-images/woman-looking-at-cellphone.jpeg" alt loading="lazy" width="400" height="200">
<p>The engaging content digital natives need, in the format they prefer, at a price point they expect.
<a href="#" tabindex="-1">Explore eTextbooks</a>
</p>
</div>
</div>
</div>
<button type="button" class="next fas fa-chevron-right" aria-label="Next Slide"></button>
<div class="navigation" role="group">
<button type="button"><span class="hidden">Slide 1 - MyLab</span></button>
<button type="button"><span class="hidden">Slide 2 - Mastering</span></button>
<button type="button"><span class="hidden">Slide 3 - Revel</span></button>
<button type="button"><span class="hidden">Slide 4 - eTextbooks and Pearson+</span></button>
</div>
</div>
:root {
--carousel-height: 30%;
--slide-width: calc(100% / 1);
}
* {
box-sizing: border-box;
}
body {
background-color: #f5f5f5;
padding: 20px;
font-family: 'Open Sans",', sans-serif;
}
.carousel {
position: relative;
width: calc(100% - 40px);
max-width: 500px;
height: var(--carousel-height);
margin: 0 auto;
padding: 0 20px;
}
.previous,
.next {
display: flex;
justify-content: center;
align-items: center;
padding: 5px 10px;
position: absolute;
top: calc(50% - 16px);
cursor: pointer;
font-size: 32px;
border: 0;
background: none;
}
.previous {
left: -30px;
}
.next {
right: -30px;
}
.slides {
list-style: none;
padding: 0;
margin: 0;
display: flex;
width: 100%;
overflow: hidden;
}
.slide {
flex: 0 0 calc(100% / 1 - 10px);
margin: 0 5px;
padding: 20px;
height: var(--carousel-height);
display: flex;
align-items: center;
font-size: 16px;
line-height: 20px;
}
@media screen and (max-width: 768px) {
.slide {
font-size: 14px;
line-height: 18px;
align-items: flex-start;
}
}
@media only screen and (max-width: 480px) {
:root {
--carousel-height: 50%;
--slide-width: 100%;
}
.carousel {
width: 100%;
padding: 0;
}
.previous,
.next {
top: calc(50% - 12px);
font-size: 24px;
}
.previous {
left: 0;
}
.next {
right: 0;
}
.slides {
margin: 0;
}
.slide {
width: 100%;
}
.card {
height: 100%;
}
img {
max-width: 100%;
height: auto;
}
}
.slide a {
color: #007a9c;
font-weight: bold;
text-decoration: none;
margin-top: 1.5rem;
}
.navigation {
display: flex;
justify-content: center;
align-items: center;
}
.navigation button {
display: inline-block;
width: 17px;
height: 17px;
margin: 0 5px;
border-radius: 50%;
background-color: #fff;
border: 3px solid #000;
cursor: pointer;
}
.navigation button.active {
opacity: 1;
width: 23px;
height: 23px;
background-color: #000;
}
.navigation button:focus {
outline: 0.15em solid #000;
outline-offset: 1px;
}
h2 {
font-size: 1.4rem;
margin-top: 0.5em;
margin-bottom: 0.2em;
line-height: 1;
}
.cards {
display: flex;
flex-direction: row;
justify-content: center;
flex-wrap: wrap;
list-style: none;
margin: 0;
padding: 0;
}
.cards > * {
flex: 0 1 25em;
}
.card {
margin: 0.75em;
padding: 0.75em;
border-radius: 3px;
border: 2px #ccc solid;
border-radius: 0.6em;
background-color: white;
position: relative;
}
img {
width: 100%;
height: auto;
}
.reorder {
display: flex;
flex-direction: column;
}
.reorder img {
max-width: 100%;
order: -1;
}
.card > * a,
.card > .cta {
display: block;
}
.card h2 > a {
text-decoration: none;
color: inherit;
}
.linkify:hover {
cursor: pointer;
box-shadow: 0 0 0 3px rgba(38, 50, 190, 0.8);
}
.cards .isfocused {
outline: 0;
box-shadow: 0 0 0 3px rgba(38, 50, 190, 0.8);
}
.isfocused a:focus {
outline: none;
}
.card .cta {
text-decoration: underline;
color: #242ac1;
font-weight: bold;
}
.hidden {
border: 0;
clip: rect(0, 0, 0, 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
h1 {
text-align: center;
}
sup {
top: -0.6em;
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
.carousel-controls {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 10px; /* Adjust as needed */
}
.toggle-button {
background: transparent;
border: medium none;
cursor: pointer;
border-radius: 50%;
width: 32px;
height: 32px;
margin: 0;
padding:0;
&:hover, &:focus {
outline: 2px solid #000;
outline-offset: 2px;
}
}
.toggle-button .play-pause {
width: 32px;
height: 32px;
}
var previousButton, nextButton, cardlink;
var slidesContainer, slides, slideDots, toggleButton;
var leftMostSlideIndex = 0;
var slideGap = 5;
var autoPlayInterval;
var isAutoPlay = true;
window.addEventListener("DOMContentLoaded", function (e) {
previousButton = document.querySelector(".previous");
nextButton = document.querySelector(".next");
slidesContainer = document.querySelector(".slides");
slides = slidesContainer.querySelectorAll(".slide");
slideDots = document.querySelectorAll(".navigation button");
toggleButton = document.querySelector(".toggle-button");
cardlink = document.querySelectorAll(".card a");
previousButton.addEventListener("click", previousSlide);
nextButton.addEventListener("click", nextSlide);
toggleButton.addEventListener("click", toggleAutoPlay);
slideDots.forEach(function (dot) {
dot.addEventListener("click", function (e) {
goToSlide(Array.prototype.slice.call(slideDots).indexOf(e.target));
});
});
startAutoPlay(); // Start autoplay when the page loads
});
function startAutoPlay() {
autoPlayInterval = setInterval(function () {
if (isAutoPlay) {
nextSlide();
}
}, 3000); // Change slides every 3 seconds (adjust as needed)
}
function toggleAutoPlay() {
isAutoPlay = !isAutoPlay;
updateToggleButton();
}
function updateToggleButton() {
if (isAutoPlay) {
slidesContainer.setAttribute('aria-live', 'off');
toggleButton.setAttribute('aria-label', 'Pause slides');
toggleButton.innerHTML =
'<svg viewBox="0 0 512 512" width="32" class="play-pause" aria-hidden="true"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-16 328c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160zm112 0c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v160z"></svg>';
} else {
slidesContainer.setAttribute('aria-live', 'polite');
toggleButton.setAttribute('aria-label', 'Play slides');
toggleButton.innerHTML =
'<svg viewBox="0 0 512 512" width="32" class="play-pause" aria-hidden="true"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z" /></svg>';
}
}
function previousSlide() {
if (leftMostSlideIndex > 0) {
goToSlide(leftMostSlideIndex - 1);
// slides[leftMostSlideIndex].setAttribute('aria-hidden', false);
} else {
goToSlide(slides.length - 1);
// slides[leftMostSlideIndex].setAttribute('aria-hidden', true);
}
}
function nextSlide() {
if (leftMostSlideIndex < slides.length - 1) {
goToSlide(leftMostSlideIndex + 1);
// slides[leftMostSlideIndex].setAttribute('aria-hidden', false);
} else {
goToSlide(0);
}
}
function goToSlide(nextLeftMostSlideIndex) {
const slideWidth = slidesContainer.offsetWidth / 1;
const newScrollLeft = slideWidth * nextLeftMostSlideIndex;
slidesContainer.scrollTo({
left: newScrollLeft,
behavior: "smooth"
});
slideDots.forEach(function (dot, index) {
if (index === nextLeftMostSlideIndex) {
dot.classList.add("active");
dot.setAttribute("aria-current", "true");
} else {
dot.classList.remove("active");
dot.setAttribute("aria-current", "false");
}
});
for (let i = 0; i < slides.length; i++) {
if (i === nextLeftMostSlideIndex) {
slides[i].setAttribute("aria-hidden", false);
cardlink[i].removeAttribute("tabindex");
} else {
slides[i].setAttribute("aria-hidden", true);
cardlink[i].setAttribute("tabindex", "-1");
}
}
leftMostSlideIndex = nextLeftMostSlideIndex;
}
MyLab
Data-driven guidance to help improve results with engaging, interactive content by expert authors. Explore MyLab
Mastering
Tools to help create immersive science & engineering courses that increase engagement. Explore Mastering
Revel
A dynamic mobile reading experience that blends digital text and media to bring concepts to life. Explore Revel
eTextbooks and Pearson+
The engaging content digital natives need, in the format they prefer, at a price point they expect. Explore eTextbooks