Skip to main content
WCAGrules
Quick navigation

Guides · Interface patterns

Video Players, Where Custom Controls Go Wrong

The native player is accessible. Almost every replacement for it is not.

Last reviewed August 30, 2026

Browsers ship a video player that is keyboard operable, announces its controls, and does its best with the viewer's own caption settings. Teams replace it because it looks different in Safari, and the replacement usually loses all three.

W3C's own advice about this is blunter than ours used to be. Rather than building a player, use one built for the job, and it names three that support audio description properly. AblePlayer, video.js, and OzPlayer. That is the recommendation from the standards body, and it is worth putting to a team before they start.

Captions, transcripts and audio description are covered in the media guide. This page is about the player around them.

What a Player Has to Do at All

W3C's list is short and it is a better starting brief than a pile of ARIA. The player has to be operable without a mouse, through a speech interface, when the page is zoomed larger, and with a screen reader running. The keyboard focus indicator has to be visible. Controls and information need clear labels. And text, controls and backgrounds need enough contrast between them.

Three things beyond that are what separate a good player from a compliant one. Playback speed control, which helps anybody who needs more processing time. Caption customization, meaning text style, size, color and position. And the ability to read the captions with a screen reader and a braille display, which is the only route into a video for somebody who is both deaf and blind.

Every Control Needs a Name and the Right Keys

Play, pause, mute, volume, the scrub bar, fullscreen, captions. Every one has to be reachable by Tab, announced as what it is, and operable by the keys its role promises. That last clause is where a blanket instruction goes wrong, because buttons and sliders answer to different keys and half your controls are sliders.

  • A play button built from a div with a triangle in it announces as nothing. Use a real button, or you have failed 4.1.2 before anything else. A button answers Enter and Space.
  • A toggle has to report its state, and there are two ways to do it that must not be combined. Either aria-pressed with a label that never changes, or a label that changes with the state and no aria-pressed at all. Mute becoming Unmute and carrying aria-pressed="true" announces the state twice, in two different words.
  • The scrub bar is a slider, not a button. It needs arrow keys for single steps, and Home and End to jump to the start and the end, which are the two most useful keys on the control and the ones most often missing. Page Up and Page Down for larger jumps are a sensible extra.
  • A slider needs four properties, not one. aria-valuenow, aria-valuemin, aria-valuemax, and an accessible name. And it needs aria-valuetext, because a raw number is not a time. Without it a screen reader announces four hundred and thirty-seven. With it, seven minutes seventeen seconds.
  • Volume is a slider and mute is a separate toggle. Combining them into one control leaves somebody with no way to do one without the other.

Controls that appear on hover

A control bar that only shows on mouseover is unreachable for a keyboard user. Show it on focus as well, and keep it visible while anything inside it has focus. Content revealed on hover also owes the three conditions, which are dismissible, hoverable and persistent. And watch the opposite problem once the bar is always visible. A bar pinned to the bottom of the viewport is sticky content, and a focused control sitting completely underneath it is a 2.4.11 failure that only shows up when you tab back up the page.

Autoplay Is the First Thing to Remove

Audio that starts on its own and runs for more than three seconds needs handling under 1.4.2, at Level A. The rule offers two routes and most write-ups name one. Either a mechanism to pause or stop the audio, or a mechanism to control its volume independently of the system volume. One is enough. What does not count is telling somebody to mute their computer, because muting the system is not pausing or stopping anything.

The reason this one is Level A rather than a matter of taste is specific. Somebody using a screen reader cannot hear their own speech output over your video, so an autoplaying soundtrack does not annoy them, it removes their ability to use the page at all. W3C's own position goes past the rule as well. It discourages starting sounds automatically and encourages sound to start from an action the user took.

Moving video without sound engages 2.2.2 Pause, Stop, Hide instead, and with a condition worth knowing. The moving-content half applies where the motion starts automatically, lasts more than five seconds, and sits in parallel with other content. A video playing full screen with nothing beside it is not in parallel with anything, which is why W3C's own worked example of a full-screen advertisement needs no pause control at all.

Let People Change the Captions

Captions burned into the picture are pixels. They cannot be turned off, restyled, or read by a braille display, and that last one is the argument that matters, because it is the difference between a deafblind viewer reaching your video and not.

Be careful how you say the rest of it, though, because the obvious criteria do not apply. The resize rule excepts captions outright, and the text spacing rule excludes captions embedded directly into video frames by name. So burned-in captions do not fail either of those. Where they can fail is contrast, since captions inside the picture are images of text and that criterion covers images of text. The case for a real caption file is user need, and it is a strong one.

A caption file arrives through a track element, and the kind attribute decides what it is. captions for a transcription of dialogue, sound effects and musical cues, meant for when sound is unavailable. subtitles for dialogue translated into another language, meant for when sound is available but not understood, and that is the default value if you leave kind off. descriptions for audio descriptions of the visual content. Plus chapters and metadata. Files must be WebVTT, one track per element can carry default, and you cannot have two tracks sharing the same kind, language and label.

You can style the caption text yourself with the ::cue pseudo-element. What you should not promise a client is that a viewer's own operating system caption preferences will come through, because support for caption styling across browsers and players is inconsistent and sometimes unreliable, and most web video ends up in the player's default of white text in a black box. Treat inheriting the viewer's settings as a benefit of the native player rather than a guarantee of it.

One warning about a description track. kind="descriptions" is an advisory technique rather than a sufficient one, and browser support for it has historically been poor, which is exactly why W3C names specific players for this job. A description track needs a player that will actually play it. Extended audio description, where the video pauses so a longer description can fit, has only one markup-based route and support for it is very limited, which is the honest answer when a client asks about the AAA criterion.

Keyboard Shortcuts Need Care

Single-character shortcuts, such as K for play and F for fullscreen, are what 2.1.4 is about. The audience it protects is not people who find shortcuts inconvenient. It is speech input users, whose dictation lands in the page as keystrokes and fires your shortcuts by accident in the middle of a sentence.

The criterion gives three escapes and you only need one. Provide a way to turn the shortcut off. Provide a way to remap it so it includes a non-printable key such as Control or Alt. Or make it active only while the component it belongs to has focus. That third one is what most players should do, and the second one is the route almost nobody mentions.

The Thing Nobody Tests

Play the video with a screen reader running and your eyes shut. Then do the four things this page is actually about. Tab to every control and confirm you can tell what each one is. Move the scrub bar with the arrows and listen to what it says, then press Home and End. Toggle mute and listen to whether the state arrives once or twice. And Shift-Tab back up the page with the control bar showing, watching for a focused control that disappears underneath it.

Common questions

Is YouTube's embedded player accessible?
It has keyboard support and real caption tracks, and we have not tested it end to end ourselves, so treat that as a reasonable default rather than a verdict. W3C's own answer to the same question is to use a player developed specifically for accessibility, and it names AblePlayer, video.js and OzPlayer as ones that support audio description. If you cannot use the browser's native controls, that list is the place to start.
Do we need audio description as well as captions?
Only where the picture carries information the soundtrack does not. The rule says so directly. If all the important information in the video track is already in the audio track, no additional description is necessary. A talking head needs none. A product demo where somebody says you just click here needs it badly.
Does autoplay always fail WCAG?
Autoplaying audio for more than three seconds needs one of two things, either a way to pause or stop it or a way to control its volume independently of the system volume. Telling people to mute their computer is not one of them. Silent moving video is a different rule, and that one only applies where the motion runs alongside other content, so a full-screen video with nothing beside it is outside it.
What keys should the scrub bar respond to?
Arrow keys for single steps, Home and End to jump to the start and the end, and optionally Page Up and Page Down for larger jumps. It is a slider, so Enter and Space do nothing on it. It also needs aria-valuetext, because without it a screen reader reads the raw seconds count instead of a time.

Sources

Keep reading

More on interface patterns

Reading about it is the cheap part.

Find out where your site actually stands. The free scan checks 10 pages in a real browser against all 90 supported automated rules, keeps its 27 best-practice checks separate from WCAG findings, and names the rule behind every finding. The full audit adds an expert review and a real blind screen-reader user. From $499, with the report in 5 business days on Rapid and 10 on Standard, and the clock starting at cleared payment.

Go somewhere useful

Find tools, resources and your workspace.

29 destinations