Audio (<audio>)
Before HTML5, playing audio in a browser meant relying on a plugin like
Flash or QuickTime. The <audio> element made sound a native part of the
web platform — a built-in player, a JavaScript API to control it, and no
plugins required.
Basic Usage
audio-basic.html
<audio src="podcast-episode-1.mp3" controls></audio>
That single line renders a native player with play/pause, a seek bar, volume control, and (in most browsers) a download/options menu — all without a byte of JavaScript.
Key Attributes
Attribute | Effect |
|---|---|
| Shows the browser’s native play/pause/volume UI. Omit it if you plan to build your own controls with JavaScript. |
| Starts playback automatically on load — heavily restricted by browsers (see below). |
| Restarts playback automatically when it reaches the end. |
| Starts (and stays, until changed) with the volume muted. |
| Hints how much to load ahead of time: |
audio-attributes.html
<audio src="ambient-loop.mp3" controls loop preload="auto"></audio> <!-- Muted autoplay background audio (still likely blocked — see warning) --> <audio src="background.mp3" autoplay muted loop></audio>
preload in Detail
Value | Meaning |
|---|---|
| Don't preload anything — good when you're not sure the user will play it (e.g. many players on one page). |
| Load only duration/dimensions, not the audio data itself. A common default compromise. |
| Let the browser decide — often means "load as much as reasonably possible" ahead of playback. |
preload entirely — for example, on a metered mobile connection many browsers won't preload regardless of the value you set.Multiple <source> for Format Fallback
Not every browser supports every audio codec. Instead of a single src on
the <audio> tag, you can provide multiple <source> children — the
browser picks the first one whose type it can play.
audio-sources.html
<audio controls> <source src="episode-1.opus" type="audio/ogg; codecs=opus" /> <source src="episode-1.aac" type="audio/aac" /> <source src="episode-1.mp3" type="audio/mpeg" /> Your browser doesn't support HTML5 audio. <a href="episode-1.mp3">Download the audio file</a> instead. </audio>
Sources are tried in order — put your preferred/smallest format first.
Text (and any markup) inside
<audio>after the<source>elements is fallback content shown only if the browser supports neither<audio>nor any listed source.MP3 and AAC have near-universal support today, making a single
<audio src="...">often good enough — multiple sources matter most for smaller/free codecs like Opus/Vorbis.
Autoplay Restrictions
Every major browser restricts autoplay with sound to prevent an
unpleasant, spammy web. The specifics differ, but the general rule is
consistent:
Autoplay with sound is usually blocked unless the user has previously interacted with the site, or the site has built up a "media engagement" history.
Autoplay is reliably allowed only when the element is also
muted.Calling
.play()from JavaScript returns a Promise that rejects if autoplay was blocked — always handle that rejection instead of assuming playback started.
autoplay-handling.html
<audio id="player" src="track.mp3"></audio>
<script>
const player = document.getElementById('player');
player.play().catch((error) => {
console.log('Autoplay was blocked:', error);
// Show a "tap to play" button instead
});
</script>Basic JavaScript Control
audio-js-control.html
<audio id="player" src="track.mp3"></audio>
<button id="play-pause">Play</button>
<script>
const player = document.getElementById('player');
const btn = document.getElementById('play-pause');
btn.addEventListener('click', () => {
if (player.paused) {
player.play();
btn.textContent = 'Pause';
} else {
player.pause();
btn.textContent = 'Play';
}
});
</script>controls for a native player, provide multiple <source> elements for codec fallback, never rely on unmuted autoplay, and always handle the rejected Promise from .play().