HTML Audio
<audio> element lets you embed sound files directly in a page — no plugins, no Flash. You control playback, offer multiple formats for browser compatibility, and make it accessible by providing a text transcript. This lesson covers everything from the simplest one-liner to the full multi-source accessible pattern.
The audio Element
At its most basic, <audio> needs just two things: a source and the controls attribute. Without controls, the audio plays in complete silence with no UI — almost never what you want.
<!-- Simplest form — single format --> <audio src="podcast.mp3" controls></audio> <!-- Better — multiple formats for browser compatibility --> <audio controls> <source src="podcast.ogg" type="audio/ogg"> <source src="podcast.mp3" type="audio/mpeg"> <!-- Fallback content for ancient browsers --> <p>Your browser doesn't support audio. <a href="podcast.mp3">Download the file</a>. </p> </audio>
The browser tries each <source> in order and uses the first one it can play. The text fallback inside <audio> only shows in browsers that don't support the element at all — which is essentially only IE8 and below today.
Audio Formats & Browser Support
Every browser supports MP3 — it's safe to use as your only format. Add OGG as a secondary source for completeness. AAC (used in .m4a files) is also universally supported but is essentially equivalent to MP3 for web use.
| Format | MIME type | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|---|
| MP3 (.mp3) | audio/mpeg | Yes | Yes | Yes | Yes |
| OGG (.ogg) | audio/ogg | Yes | Yes | No | Yes |
| AAC (.m4a) | audio/mp4 | Yes | Yes | Yes | Yes |
| WAV (.wav) | audio/wav | Yes | Yes | Yes | Yes |
| WebM (.webm) | audio/webm | Yes | Yes | No | Yes |
Attributes Reference
<!-- Autoplay only works reliably when muted --> <audio autoplay muted loop preload="auto"> <source src="ambient.mp3" type="audio/mpeg"> </audio> <!-- Podcast — metadata only, no buffering until play --> <audio controls preload="metadata"> <source src="episode-42.mp3" type="audio/mpeg"> </audio>
autoplay muted is allowed everywhere. Never autoplay audio with sound — it's an accessibility violation and will be blocked anyway. Use autoplay muted only for ambient/background tracks where starting muted is intentional.Accessibility — Transcripts
Audio content must be accessible to deaf users and anyone who can't play audio (library, noisy environment). The requirement: provide a text transcript. Unlike video captions (which are synchronized), an audio transcript is simply the full spoken content as readable text — placed near the player or on a linked page.
<figure> <figcaption>Episode 42: CSS Grid Deep Dive (28 min)</figcaption> <audio controls preload="metadata"> <source src="ep42.ogg" type="audio/ogg"> <source src="ep42.mp3" type="audio/mpeg"> </audio> </figure> <!-- Transcript — either inline or linked --> <details> <summary>Read transcript</summary> <div class="transcript"> <p><strong>Host:</strong> Welcome to episode 42...</p> <p><strong>Guest:</strong> Thanks for having me...</p> </div> </details>
Using <details>/<summary> for the transcript is a clean pattern — the transcript is always in the page (good for SEO and screen readers) but collapsed by default so it doesn't clutter the visual layout.
Requirements:
- An <article> wrapping the episode content
- The episode title in an <h1>, episode number and date in a <header> using <time datetime>
- A <figure> containing the <audio> player with: two <source> elements (OGG first, MP3 second), preload="metadata", controls, and a <figcaption> with the episode title
- A short episode description paragraph
- A transcript section using <details>/<summary> containing at least 4 speaker-labeled paragraphs
- An <aside> with 3 "related episodes" links
Bonus: Style the <details> transcript with a smooth CSS transition and a custom open/close icon using the [open] attribute selector.
Show hints
- Two sources: <source src="ep.ogg" type="audio/ogg"> then <source src="ep.mp3" type="audio/mpeg">
- details[open] summary::before { content: '▼' } vs summary::before { content: '▶' }
- The transcript div inside details can have max-height: 0 overflow:hidden transition on open
- Wrap everything in an article + aside inside main for full semantic correctness