Search topics
Autoplaying sound with no way to stop it
A hero video starts with its soundtrack on, and the page has no control that pauses or mutes it.
<video src="our-story.mp4" autoplay loop> The problem
Screen reader users can't hear their screen reader over the soundtrack, so they can't find a way to stop it.
A coffee roaster's home page opens on a short banner film of roasted beans tumbling onto a pile. The film starts by itself, loops, and plays its music out loud. The video has no controls, and nothing else on the page pauses or mutes it.
Success criterion 1.4.2 allows sound to start by itself only if it stops within three seconds, or if the page gives a way to pause or stop it, or to turn its volume down apart from the system volume. Here the video has the autoplay attribute, no muted attribute, no controls and no button of its own, so the soundtrack plays for as long as the page is open.
It also catches out anyone in a quiet office, a library or on a train, who often closes the tab rather than look for the source.
3 of 10 groups affected
- No vision (affected)
- Low vision (not affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (affected)
- No speech (not affected)
- Motor (not affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Without vision The soundtrack plays over the screen reader's speech, so people can't hear the page, or the control that would stop it. Turning the computer's volume down silences the screen reader too.
- Limited hearing With some hearing, a second sound under the screen reader or a voice makes both hard to follow, and hearing aids raise the soundtrack along with everything else.
- Limited language, cognitive and learning abilities Sound that starts by itself pulls attention away from the page, and people who are easily distracted or overwhelmed by sound can't settle to read until it stops.
Browsers block sound that starts by itself on a first visit, so a tester who pastes the address into a fresh browser, and every headless audit, hears nothing. Chrome allows the same sound once the visitor has clicked something on the site, so someone who arrives from another of its pages hears the film at once. axe flags autoplay without muted or controls, but only for a person to confirm. It never sees sound that a script starts with play(). AI fixes often add muted and leave out any pause button, which silences the film but leaves a looping video that nobody can pause.
Try it
Play the short film, then try to stop it with the keyboard.
Try with sound stands in for the film starting with its sound on, since this page never plays sound by itself. Then Tab through the page and watch the screen reader preview. Apply a fix to find the film’s own buttons.
Broken Can you fix this?
Screen reader preview (simulated)
Tab to a link or a button.
A recreated demo. The broken version is intentionally inaccessible.
The fix
Let people start the sound: the film waits for Play, or starts muted with a button to turn the sound on.
- 1Only sound the visitor started plays for more than three seconds.
- 2Turn sound off with a control on the page, never by asking people to lower the system volume.
- 3Put the
mutedattribute in the HTML of every video that plays by itself.
<section class="hero"> <video src="our-story.mp4" autoplay loop playsinline></video> <h1>Roasted in small batches</h1></section>The film waits for Play
<section class="hero"> <video id="film" src="our-story.mp4" poster="our-story.jpg" loop playsinline aria-hidden="true"></video> <h1>Roasted in small batches</h1> <button type="button" id="play" class="film-button"> <svg aria-hidden="true" focusable="false"><use href="#icon-play"></use></svg> <span class="visually-hidden">Play film</span> </button></section><script> const film = document.getElementById('film'); const play = document.getElementById('play'); // The icon and the hidden name change together. const set = (button, icon, name) => { button.querySelector('use').setAttribute('href', icon); button.querySelector('.visually-hidden').textContent = name; }; play.addEventListener('click', () => (film.paused ? film.play() : film.pause())); const show = () => set(play, film.paused ? '#icon-play' : '#icon-pause', film.paused ? 'Play film' : 'Pause film'); ['play', 'pause'].forEach((type) => film.addEventListener(type, show));</script>The film starts with sound wherever the browser allows it, and plays on in a loop. With no controls and no other button, the only way to silence it is to leave the page or turn down the whole computer, screen reader included.
Without autoplay, nothing plays until someone presses Play, so the page is quiet when it opens, and the poster gives the hero its picture until then. The button is a real <button>, so it works from the keyboard, and once the film plays the same button pauses it. Its icon and its hidden name come from the film's real state, so they stay right even if playback fails.
Both pass 1.4.2. Waiting for Play costs nothing and is quiet for everyone: choose it when the film's point is what it says, or when it is not needed to make the page look finished. Starting muted keeps the moving picture the design was built around, and costs only the sound on arrival, which most browsers would have blocked anyway: choose it when the film is a moving backdrop.
Hero films rarely show the browser's control bar, so the snippets give the film round icon buttons of its own. They are real <button> elements, so they need no ARIA role, and an icon alone is fine on screen as long as each of these holds.
- The name is in the code: hidden text such as "Pause film", or an
aria-label, with the icon markedaria-hidden="true". Hidden text is translated by browser translation tools, which do not always translatearia-label. - The icon has 3:1 contrast against what is behind it (1.4.11). Over moving footage that means a solid dark disc under a white icon, which is what
.film-buttonstands for here, alongside the usual.visually-hiddenclass. - The button is at least 24 by 24 pixels (2.5.8); 44 is the usual size for a control floating over a film.
- The focus ring shows against the film.
- The icon and the name change together: the pause icon with "Pause film", the play icon with "Play film".
Play, pause and speaker icons are familiar enough to stand alone. A tooltip on hover and focus is optional, and if you add one it has to meet 1.4.13 (Content on Hover or Focus). A button that changes its name when pressed is not announced again by every screen reader, so check it with the ones your users have.
Native controls pass too, and are the better choice for a film people sit and watch, such as a product video; they also bring a captions menu, which buttons of your own have to provide when the film has speech.
A banner film that only sets the mood needs nothing read about what it shows, so the snippets hide it with aria-hidden="true" and let the buttons say what they control. That works only while the film has no controls of its own: on a <video controls> it would hide focusable buttons, so give such a film a short name instead, such as aria-label="Banner film". Either way, hiding a film from screen readers does nothing to its sound. Screen readers announce nothing when media starts, so the music simply plays over their speech.
A third way passes 1.4.2 on paper, but is not a fix to plan around: let the sound start by itself, with a "Turn off sound" button first on the page (technique G170). It falls short in three ways.
- Browsers block the very sound it protects on a first visit, so the design rarely plays as intended.
- Screen reader users still have to find the button while the music talks over their screen reader.
- It passes only while the button stays first, so a cookie banner or skip link added later quietly breaks it.
If a page really must start sound by itself, keep that button first, and in words rather than a lone icon.
A sound that ends within three seconds needs no control, which is why a short chime is fine. That is no way out for a long soundtrack: cutting it to three seconds changes the content more than adding a Play button does.
A volume slider inside the page counts as a control too, provided it changes only this page's sound. The system volume never counts, because it also controls the screen reader.
Sound that starts by itself does not only come from a video tag with autoplay. Each of these plays automatically in the sense of 1.4.2, and each takes the same fixes.
- Background music players, common on brand and restaurant sites: start them off, with a labelled button to turn them on.
- Embedded players from YouTube or Vimeo with autoplay switched on in their address: also switch on their mute option, and leave their controls showing.
- Scripts that call
play()on the visitor's first click anywhere on the page: that click opened a menu or followed a link, so it was not a request for sound.
Some frameworks set muted as a property after the page loads instead of writing the attribute. Check the served HTML for the attribute, and check in the browser that the film is silent from the first frame.
Whichever fix you choose, a film with speech needs captions, and with buttons of your own, a way to turn them on. This banner has only music, so its snippets leave captions out.
Fixing this with an AI coding assistant? Get this guide as Markdown
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Autoplay settings
Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the hero or any embedded player changes.
Limits
This is a starting pattern, not a guarantee for every application. Browsers change their autoplay rules, so a page that is silent today in one browser may not be tomorrow in another. Test the complete journey with your target browsers and assistive technology.
This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.