Accessible Image Sliders and Carousels: Pause Controls, Keyboard and Alt Text
Short answer: An accessible carousel lets users pause or stop auto-rotation (WCAG 2.2.2), operate every control by keyboard, hear slide changes only when they ask for them, and read alt text on each slide image. If that is more than your store needs, a single static hero image is simpler and safer.
Auto-rotating hero sliders are common on store homepages. They are also one of the more frequent sources of accessibility problems, because motion, timing, keyboard use and screen reader announcements all have to work together.
This guide covers what a slider needs to meet WCAG 2.1 AA, a minimal markup pattern, and when it makes more sense to drop the carousel for a static hero. It is general information, not legal advice. For legal questions, talk to an attorney.
Why carousels cause problems
A carousel changes content without the user asking it to. That creates trouble for several groups:
- People with reading or cognitive disabilities may not finish reading a slide before it changes.
- People with low vision or motor impairments may not be able to reach a link or button before the slide moves on.
- Keyboard users can lose their place if focus lands on content that disappears.
- Screen reader users may hear constant interruptions, or hear nothing at all if the controls are unlabeled.
- People sensitive to motion can be distracted or made uncomfortable by constant movement.
Most carousel failures come down to a few success criteria, covered below.
The requirements that matter most
| Issue | WCAG criterion | What it means for a slider |
|---|---|---|
| Auto-rotation | 2.2.2 Pause, Stop, Hide | Moving content that starts automatically, lasts more than five seconds and appears alongside other content needs a way to pause, stop or hide it |
| Controls by keyboard | 2.1.1 Keyboard | Previous, next, pause and any slide indicators must work without a mouse |
| Visible focus | 2.4.7 Focus Visible | Keyboard focus must be clearly visible on every control and link |
| Control names and roles | 4.1.2 Name, Role, Value | Buttons need accessible names and correct state, such as whether rotation is paused |
| Images | 1.1.1 Non-text Content | Informative slide images need text alternatives |
| Text in images | 1.4.3 Contrast (Minimum) | Text laid over photos needs enough contrast against the part of the image behind it |
1. Give users a pause or stop control (WCAG 2.2.2)
If your slider starts rotating on its own, WCAG 2.2.2 expects a mechanism to pause, stop or hide it. A visible pause button is the most common way to meet this.
Practical points:
- Place the button in the DOM before the slides, so keyboard and screen reader users meet it early.
- Make it a real
<button>with a clear name, such as "Pause slideshow", and switch the name to "Start slideshow" when paused. - Keep it visible. Hiding it until hover fails for keyboard and touch users.
- Do not restart rotation on its own after the user has paused it.
- Pausing on hover or focus is a helpful extra, but on its own it generally does not replace a dedicated control.
The simplest way to satisfy 2.2.2 is to not auto-rotate at all. A carousel that changes only when the user presses next or previous avoids the issue entirely.
2. Make every control keyboard operable (WCAG 2.1.1)
Native <button> elements work with Enter and Space and receive focus by default. Avoid building controls from <div> or <span> elements, which then need extra roles, tab stops and key handlers to behave like buttons.
Check that:
- Previous, next, pause and any dot or thumbnail indicators can all be reached with Tab and activated with Enter or Space.
- The tab order follows the visual order.
- Swipe-only or drag-only interaction always has a button alternative.
- Focus styling is visible against the slide background.
You can test this yourself in a few minutes with the 5-minute keyboard accessibility test.
3. Announce slides carefully
Screen reader users need to know what the carousel is and which slide they are on, but they should not be interrupted every few seconds.
- Wrap the carousel in a region with an accessible name, using
role="region"(or a<section>) plusaria-label. The ARIA Authoring Practices Guide at w3.org describes a carousel pattern usingaria-roledescription="carousel"; use that attribute sparingly and test it, since support and behavior vary. - Label each slide so users know their position, for example "1 of 4".
- Use
aria-live="off"while the carousel auto-rotates, so slide changes are not announced unprompted. - Switch to
aria-live="polite"when rotation is stopped or when the user presses next or previous, so the change they asked for is announced.
4. Write useful alt text for slide images
Each slide image needs an alternative that matches its purpose (see Non-text Content):
- If the image is decorative and the headline text sits beside it, use empty alt text (
alt=""). - If the image carries the message, such as a sale banner with text baked into it, the alt text should state that message.
- If the whole slide is a link, make sure the link has a name that describes where it goes. See Link Purpose.
Better still, keep real text as live HTML on top of the image rather than burning it into the picture. For more on writing descriptions, see alt text for product images.
5. Don't lose focus when slides change
A common failure is moving focus to a slide, or removing the slide that holds focus, when the carousel advances. Aim for this behavior:
- Rotation never moves keyboard focus.
- If a user is focused on a link inside a slide, pause rotation while focus is within the carousel.
- When the user presses next or previous, focus stays on that button.
- Slides that are not visible are removed from the tab order and from the accessibility tree, using
hidden,display: noneorinert, so users cannot tab into content they cannot see.
A minimal accessible pattern
This is a starting point, not a finished component. Adapt it and test it with a keyboard and a screen reader.
<section class="carousel" aria-label="Featured collections">
<div class="carousel-controls">
<button type="button" id="toggle" aria-label="Pause slideshow">Pause</button>
<button type="button" id="prev" aria-label="Previous slide">Previous</button>
<button type="button" id="next" aria-label="Next slide">Next</button>
</div>
<div class="slides" id="slides" aria-live="off">
<div class="slide" role="group" aria-label="1 of 3">
<a href="/collections/summer">
<img src="summer.jpg" alt="Summer collection: linen shirts and shorts">
</a>
</div>
<div class="slide" role="group" aria-label="2 of 3" hidden>
<a href="/collections/sale">
<img src="sale.jpg" alt="End of season sale, up to 30% off">
</a>
</div>
<div class="slide" role="group" aria-label="3 of 3" hidden>
<a href="/collections/new">
<img src="new.jpg" alt="New arrivals">
</a>
</div>
</div>
</section>
CSS and JavaScript notes
const slides = [...document.querySelectorAll('.slide')];
const live = document.getElementById('slides');
const toggle = document.getElementById('toggle');
let index = 0;
let timer = null;
function show(i, announce) {
live.setAttribute('aria-live', announce ? 'polite' : 'off');
slides[index].hidden = true;
index = (i + slides.length) % slides.length;
slides[index].hidden = false;
}
function start() {
timer = setInterval(() => show(index + 1, false), 7000);
toggle.textContent = 'Pause';
toggle.setAttribute('aria-label', 'Pause slideshow');
}
function stop() {
clearInterval(timer);
timer = null;
toggle.textContent = 'Play';
toggle.setAttribute('aria-label', 'Start slideshow');
}
toggle.addEventListener('click', () => (timer ? stop() : start()));
document.getElementById('next').addEventListener('click', () => { stop(); show(index + 1, true); });
document.getElementById('prev').addEventListener('click', () => { stop(); show(index - 1, true); });
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (!reduce) start(); else stop();
A few notes:
- Respecting
prefers-reduced-motionis good practice, and it also reduces the chance of a 2.2.2 problem. - Use a generous interval, but remember a long interval does not replace the pause control.
- Keep a visible focus style on every button:
.carousel button:focus-visible { outline: 3px solid #1a56db; outline-offset: 2px; }. - Make sure text over images keeps adequate contrast on every slide. See color contrast checking.
- If you use a theme or plugin carousel, test it rather than assuming it is accessible. Many are not, and settings such as autoplay are often on by default.
When to replace the carousel with a static hero
A carousel is worth keeping only if it earns its place. Consider a single static hero when:
- Only the first slide gets meaningful attention. Many stores find that later slides are rarely seen.
- You cannot maintain the pause control, labels and alt text for every slide as the content changes.
- Your theme's slider fails keyboard or screen reader testing and cannot be fixed easily.
- The message is simple enough for one image, one headline and one button.
A static hero removes the 2.2.2 issue, reduces keyboard stops, and is easier to keep accessible. If you need to feature several things, a short grid of linked cards below the hero is another option that needs no motion.
Checking your work
Test the slider on the live page, not just in a design tool:
- Reload the page and watch whether it rotates. If so, confirm you can pause it with the keyboard alone.
- Tab through all controls and links, confirming the order and visible focus.
- Turn on a screen reader and confirm the carousel is named, the slide position is clear, and the page is not interrupted by automatic changes.
- Zoom the page to 200% and confirm controls remain usable.
For a broader review, use the WCAG 2.1 AA checklist. If you want an automated starting point, you can run a free scan. Automated tools catch only some carousel issues, so manual testing is still needed.
Frequently asked questions
Does an auto-rotating slider have to have a pause button?
If the slider starts moving automatically, lasts longer than five seconds and appears alongside other content, WCAG 2.2.2 requires a way to pause, stop or hide it. A visible, keyboard-operable pause button is the usual solution. A slider that only moves when the user clicks next or previous does not raise this issue.
Is a carousel automatically an ADA violation?
No. The ADA does not name carousels, and WCAG is a technical standard rather than the statute itself. Courts and plaintiffs often point to WCAG when assessing websites, so an inaccessible slider can be cited among other issues. For how this applies to your situation, ask an attorney.
Should every slide image have alt text?
Every image needs a text alternative that fits its purpose. Informative images should describe their message, and purely decorative images should use empty alt text so screen readers skip them. If a slide image is also a link, the link needs a name that makes its destination clear.
Will an accessibility overlay fix my slider?
Overlays generally cannot fix the underlying markup, focus handling or motion behavior of a slider. Fixes usually need to be made in the slider's code or settings. See do accessibility overlay widgets prevent ADA lawsuits for more.
What is the simplest accessible alternative to a carousel?
A single static hero with real HTML text, a clear heading and one button is the simplest option. It needs no pause control, no slide announcements and no focus management. It is also easier to keep accessible when your content changes.
Related
- A 5-Minute Keyboard Accessibility Test for Your Online Store
- How to Write Alt Text for Product Images That Helps Shoppers
- WCAG 2.1 AA checklist for business websites
- ADA Website Lawsuits Against Shopify Stores: What Gets Cited
Proof of Access provides technical accessibility assessments. We are not a law firm and nothing on this page is legal advice. If you have received a demand letter or a lawsuit, talk to an attorney.