> Markdown version of [/magazine/668-html-media-elements-and-how-to-use-them-video-and-audio](https://www.wearedevelopers.com/magazine/668-html-media-elements-and-how-to-use-them-video-and-audio). Every page supports `.md` or `Accept: text/markdown`. Links point to the HTML versions so they work for humans too. Agent guide: [/agents.md](https://www.wearedevelopers.com/agents.md). --- # HTML Media Elements and How to Use Them: <video> and <audio> **By:** [Daniel Cranney](https://www.wearedevelopers.com/@daniel-cranney) **Published:** March 13, 2026 If you’ve read the WeAreDevelopers Magazine before, you’ll know we’re vocal supporters of the web platform, and of sharing the power of native HTML elements. This time, we’re taking a closer look at media elements like `<video>` and `<audio>`, and how to make the most of them. ## Multiple Sources Just as we do with fonts, it’s good to give the browser fallback options when it comes to serving media files. So, rather than pointing to a single file, you can stack `<source>` elements and the browser will use the first format it supports: <video controls> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> </video> By including the `type` attribute, browsers can skip formats it can’t play, without wasting time and data streaming the file first. As for audio, it works exactly the same way, though of course the expected formats are different: <audio controls> <source src="audio.ogg" type="audio/ogg"> <source src="audio.mp3" type="audio/mpeg"> </audio> ## The `<audio>` Element The `<audio>` element is very simple, and shares most of its attributes with `<video>`, with its most basic use looking a little like this: <audio controls src="track.mp3"></audio> But `audio` becomes more useful when you add in a few attributes. Of course `loop` and `autoplay` work as you’d expect (though autoplay is blocked by most browsers unless `muted` is also set), and `preload` let’s you decide whether you want the source files fetched on load or not. We’d advise using `preload="none"` wherever possible, to save unnecessarily loading files. The `audio` element is great for notification sounds, interactive feedback, ambient audio, and a common pattern is a hidden audio element triggered by user interaction: <audio id="chime" src="chime.mp3" preload="auto"></audio> We’ve seen this over-engineered in all kinds of ways, whereas this native element keeps everything contains and JavaScript-free. ## Accessibility The `<track>` element attaches a `.vtt` file to your media, handling captions, subtitles, and chapter navigation without any third-party tooling. <video controls> <source src="video.mp4" type="video/mp4"> <track kind="captions" src="captions-en.vtt" srclang="en" label="English" default> <track kind="subtitles" src="subs-fr.vtt" srclang="fr" label="French"> <track kind="chapters" src="chapters.vtt" srclang="en" label="Chapters"> </video> You can see above that we’ve used three different kinds of `kind` attributes, and it’s worth paying attention to why. So, `captions` include non-speech sounds like `[door slams]` and is intended for accessibility, `subtitles` is a straight transcript, intended for users who understand the language, and `chapters` creates a navigable menu inside the player automatically. Again, all of this without any JavaScript, and all native. One gotcha to look out for is that the `.vtt` file must be served from the same origin as the page, or with the correct CORS headers, and will silently fail if not. ## Controlling the UI One common reason that some devs will reach for a framework, pre-made component or bloated UI library is to be able to customise elements beyond what the native ones allow. Well, the `video` elemement has a good amount of attributres built in to do just this. The `controlsList` attribute lets you strip specific controls from the native player without replacing it entirely: <video controls controlsList="nodownload nofullscreen noremoteplayback"> <source src="demo.mp4" type="video/mp4"> </video> The three available values — `nodownload`, `nofullscreen`, and `noremoteplayback`, can be combined in any combination. It’s particularly useful for dashboards or internal tools where a minimal, non-downloadable player is preferable to a full custom build. It is worth saying this is a Chromium-only feature, and Firefox ignores it, so it’s far from perfect. ## Other Attributes Beyond `controls` and `src`, there are a handful of attributes that meaningfully change how media loads and behaves. You can set a thumbnail image before playback starts using the `poster` attribute, passing a path to your image as a string, which goes a long way toward making an embedded video feel intentional rather than like a grey box. Also, `playsinline` is essential for mobile, because without it iOS Safari forces video into fullscreen when played. Putting it all together, a production-ready embed often looks something like this: <video controls controlsList="nodownload" preload="metadata" poster="thumbnail.jpg" playsinline> <source src="video.webm" type="video/webm"> <source src="video.mp4" type="video/mp4"> <track kind="captions" src="captions.vtt" srclang="en" label="English" default> </video> Isn’t that great? No JavaScript, no framework, no libraries, and it even has fallback-files. * * * We hope you found this article useful, and if you have any tips and tricks you’d like to share with our audience then [get in touch with us on socials](https://bsky.app/profile/wearedevelopers.bsky.social). ## Related Articles - [The HTML Elements That You’re Probably Over-Engineering](https://www.wearedevelopers.com/magazine/646-the-html-elements-that-you-re-probably-over-engineering) - [3 JavaScript-Free Techniques for Accordions, Dialogs, and Table of Contents](https://www.wearedevelopers.com/magazine/684-3-javascript-free-techniques-for-accordions-dialogs-and-table-of-contents) - [Stop Using Divs: Five Input Types You Could Use Right Away](https://www.wearedevelopers.com/magazine/664-stop-using-divs-five-input-types-you-could-use-right-away) - [What Developers Really Need to Create Great Code Demos](https://www.wearedevelopers.com/magazine/658-what-developers-really-need-to-create-great-code-demos) ## Related Videos - [The Fundamentals of Online Video](https://www.wearedevelopers.com/videos/32-the-fundamentals-of-online-video) - [Catching up on the basics you don't really need that much code](https://www.wearedevelopers.com/videos/903-catching-up-on-the-basics-you-don-t-really-need-that-much-code) - [Web APIs you might not know about](https://www.wearedevelopers.com/videos/281-web-apis-you-might-not-know-about) - [WeAreDevelopers LIVE - Streaming HTML](https://www.wearedevelopers.com/videos/2135-wearedevelopers-live-streaming-html) ## Related Jobs - [Junior Frontend Engineer](https://www.wearedevelopers.com/jobs/ext/1532351-junior-frontend-engineer) at **Almedia** - [Senior Product UI Designer](https://www.wearedevelopers.com/jobs/ext/1998621-senior-product-ui-designer) at **Almedia** - [Staff Frontend Engineer](https://www.wearedevelopers.com/jobs/48313-staff-frontend-engineer) at **SMG Swiss Marketplace Group** - [Senior React Native Developer](https://www.wearedevelopers.com/jobs/ext/1518176-senior-react-native-developer) at **Almedia** - [Staff Frontend Engineer (Expert+/Lead equivalent) - Hybrid working model, 100%, Ho Chi Minh City](https://www.wearedevelopers.com/jobs/48314-staff-frontend-engineer-expert-lead-equivalent-hybrid-working-model-100-ho-chi-minh-city) at **SMG Swiss Marketplace Group** - [Software Engineer](https://www.wearedevelopers.com/jobs/ext/1304673-software-engineer) at **Bitpanda**