A common thread in dev communities right now: teams ship great video content, then realize some users cannot access it without captions, transcripts, keyboard controls, or audio descriptions. Accessibility is not just compliance, it is usability and reach.
Hi folks, I am updating our video player and need practical guidance on accessibility. Specifically: How to make videos accessible, and what is WCAG? I am looking for a concrete checklist and examples that cover captions, transcripts, audio descriptions, keyboard navigation, and format choices.
The Web Content Accessibility Guidelines (WCAG) focuses on making web content like videos and other media accessible for everyone. It’s a technical standard maintained by the World Wide Web Consortium (W3C), and outlines how websites should approach displaying content.
- Captions for prerecorded video with audio. Live captions when feasible.
- Audio descriptions or a described version for essential visual information.
- Transcript that includes dialogue and meaningful visuals, linked near the player.
- Keyboard accessible controls, visible focus, and logical tab order.
- No auto-play with audio. If you must auto-play, provide a clear pause or stop.
- Adjustable playback speed, volume, and caption styling if you use a custom UI.
- Format and delivery that work across devices and bandwidths.
<figure>
<!-- The <video> element provides the main media content with user controls -->
<video
id="howto-video"
width="640"
controls
preload="metadata"
poster="thumbnail.jpg"
aria-describedby="howto-caption"
>
<!-- Source for the main video file -->
<source src="example-video.mp4" type="video/mp4" />
<!-- Captions track for viewers who are deaf or hard of hearing -->
<track
src="captions-en.vtt"
kind="captions"
srclang="en"
label="English captions"
default
/>
<!-- Audio descriptions track for users who are blind or have low vision -->
<track
src="descriptions-en.vtt"
kind="descriptions"
srclang="en"
label="Audio descriptions"
/>
<!-- Fallback text and links for browsers that don't support video -->
<p>
Your browser does not support HTML5 video. Watch the
<a href="example-video.mp4">MP4</a> or read the
<a href="transcript.html">transcript</a>.
</p>
</video>
<!-- Figure caption provides context and acts as a video label -->
<figcaption id="howto-caption">
How to froth milk for lattes
</figcaption>
</figure>
<!-- Links to additional accessible resources: full transcript and described version -->
<p>
<a href="transcript.html">Full transcript</a> •
<a href="example-video-described.mp4">Audio-described version</a>
</p>Code language: HTML, XML (xml)
Native controls are keyboard accessible. If you build a custom UI, wire up common shortcuts:
const v = document.getElementById('product-video');
document.addEventListener('keydown', e => {
if (document.activeElement !== v) return;
switch (e.key) {
case ' ':
e.preventDefault();
v.paused ? v.play() : v.pause();
break;
case 'ArrowRight':
v.currentTime += 5;
break;
case 'ArrowLeft':
v.currentTime -= 5;
break;
case '+':
v.playbackRate = Math.min(2, v.playbackRate + 0.25);
break;
case '-':
v.playbackRate = Math.max(0.5, v.playbackRate - 0.25);
break;
}
});Code language: JavaScript (javascript)
- Offer at least MP4 H.264 and WebM for broad coverage.
- Encode efficiently for faster starts and lower battery usage. Review video encoding best practices.
- Provide multiple resolutions or adaptive bitrate so users can pick or auto-negotiate quality. Learn about the trade-offs in bitrate vs resolution.
WEBVTT
00:00:00.000 --> 00:00:02.500
Intro music and title animation
00:00:02.500 --> 00:00:06.000
Narrator: Welcome to the product tour.Code language: CSS (css)
Keep captions synchronized, concise, and include speaker IDs and non-speech audio when relevant.
After you have captions and transcripts in place, you can host and deliver accessible variants efficiently. For example, upload your video and VTT files, then reference them from your HTML with multiple formats and a poster image.
<video controls width="800"
aria-label="Product demo video"
poster="https://res.cloudinary.com/demo/image/upload/w_800,c_fill,q_auto/product-demo-poster.jpg">
<source src="https://res.cloudinary.com/demo/video/upload/f_mp4,q_auto/vproduct-demo" type="video/mp4">
<source src="https://res.cloudinary.com/demo/video/upload/f_webm,q_auto/vproduct-demo" type="video/webm">
<track kind="captions"
src="https://res.cloudinary.com/demo/raw/upload/product-demo.en.vtt"
srclang="en" label="English" default>
</video>Code language: HTML, XML (xml)
Alternatively, you can also use Cloudinary to add auto-captions to your videos dynamically, and at scale.
- Keyboard only: Can you operate play, pause, seek, volume, and speed without a mouse.
- Screen reader: Verify labels, focus order, and that captions communicate non-speech audio.
- Low bandwidth: Confirm the player starts quickly and quality can adjust.
- No motion preference: Avoid aggressive auto-play animations by default.
Provide captions, transcripts, and audio descriptions. Make controls keyboard friendly and visible, avoid auto-play with audio, and ship multiple formats and qualities. Use a reliable CDN to deliver optimized video and VTT. If you are already managing media in the cloud, you can host videos and caption files together and reference them directly in your HTML.
Ready to optimize accessible video at scale and deliver fast across devices? Create a free Cloudinary account and streamline your video pipeline.