In our previous post, where we discuss the basics of the HTML audio element, we mentioned that each individual web browser presents its own version of an audio player and that it will look different in every browser.
There is not much you can do with CSS directly (without JavaScript) on the audio
element, and since the default player is rendered by the browser itself, it doesn’t make a lot of sense to spend the time accounting for all browsers — it will be a moving target that will continuously change.
However, there are a few things you can do, and you might just want to know what they are and how this all works. Hopefully this will help.
The Audio Tag
When you create an audio player with:
<audio src="Bell.mp3" type="audio/mpeg" controls></audio>
You get something like this.
Open this page’s URL on another browser (Chrome, Firefox, Edge, Safari, etc.), and see that it is rendered slightly differently by each browser.
Each browser creates a block element for the audio
tag (i.e. display:block), and then that parent block element container holds a custom component that exists in the “shadow DOM” of the browser window. We’ll get into that later.
You can treat the parent container much like any block element in your CSS, adjusting height and width and colors. So with:
audio {height:200px; width:300px; background:yellow;}
You will end up with this
You can try it out in different browsers and still see the 300×200 yellow rectangle that contains the audio player.
You can even do some fancy animation and transitions. For example, hover over the player below:
This is done with:
audio:hover {transform: scale(1.1);filter: drop-shadow(2px 3px 3px #333);}
Too much of this sort of thing can lead to a bad user experience, so don’t over-do it. I just wanted you to know that it is possible.
Audio Tag Pseudo-Elements
Although you cannot style the child elements of the audio tag very easily in any sort of uniform, ubiquitous way, there are some pseudo-elements that your CSS can hook into for specific browsers.
You can see how the pseudo-class :hover is used above. Pseudo-elements are similar. You will find in your journey of web development that some pseudo-elements use a single colon and others use a double colon. The double colon replaced the single-colon notation for pseudo-elements in CSS3. This was an attempt from W3C to distinguish between pseudo-classes and pseudo-elements. Here we will use the double colon.
The most common pseudo-elements you find related to the audio tag are prepended by ::-webkit-media-. These WebKit-only extensions work in some browsers like Chrome and iOS, but the browser developers often change the way this functions, and it is not completely reliable.
The list of these audio element pseudo-elements is as follows:
audio::-webkit-media-controls-panel
audio::-webkit-media-controls-mute-button
audio::-webkit-media-controls-play-button
audio::-webkit-media-controls-timeline-container
audio::-webkit-media-controls-current-time-display
audio::-webkit-media-controls-time-remaining-display
audio::-webkit-media-controls-timeline
audio::-webkit-media-controls-volume-slider-container
audio::-webkit-media-controls-volume-slider
audio::-webkit-media-controls-seek-back-button
audio::-webkit-media-controls-seek-forward-button
audio::-webkit-media-controls-fullscreen-button
audio::-webkit-media-controls-rewind-button
audio::-webkit-media-controls-return-to-realtime-button
audio::-webkit-media-controls-toggle-closed-captions-button
For example, if you were to use:
audio::-webkit-media-controls-play-button{ background-color:green;}
It might look like this:

But it’s hard to say which browsers will consistently, now and in the future, appear this way.
The Shadow DOM
If you use your browser’s dev tools to inspect your audio
tag in the DOM, you will see something like this:

Notice that it is simply the single audio container element, with no way to inspect the inner parts of the player, such as the play button, the scrubber, and the volume control.
This is because the default HTML audio player is located in what is know as “the shadow DOM.” It sounds scary and mysterious, doesn’t it? The shadow DOM is a scoped subtree inside of a DOM element. What this simply means is that something in the shadow DOM is separate (has it’s own scope) and it is the same sort of tree-like structure that you are used to with parent, child, and sibling elements that are unrelated to the rest of the document object model.
Inspecting the Shadow DOM
This information changes from year to year, but currently there are ways of seeing the shadow DOM in both Google and Firefox browser dev tools.
To Inspect the Shadow DOM in Google Chrome:
- Open up Google Developer Tools (Mac:
Command+Option+I
or Windows:F12 or Control + Shift + I
) - At the top right you’ll see a three-dot ellipsis. Click on this and go to
More Tools >> Settings.
- Next, check the setting
Show user agent shadow DOM.
- Restart Chrome.
Now when you inspect your audio tag you should see something like:

To Inspect the Shadow DOM in Mozilla Firefox:
- In the Firefox address bar type in
about:config
. - You might get to a scary warning screen. Don’t be too afraid and continue on.
- Find the two settings
devtools.inspector.showUserAgentShadowRoots
devtools.inspector.showAllAnonymousContent
True
. - Restart Firefox.
It will look roughly the same as it does in Chrome, both sharing a newly discovered #shadow-root
section, but notice how the element names are not the same:

Because these shadow DOM elements are scoped, there is not much you can do to alter them with simple CSS. But it is good to know how these elements are constructed, especially if you plan to continue learning how to build your own audio player with JavaScript and HTML.
In the next lesson we will learn how to remove the controls
attribute and to make your own html audio player with custom buttons and styles using JavaScript.
Thanks this helped me so much, couldn’t figure it out myself!
You’re welcome. I’m glad it helped.
Thank you this is awesome!
You’re welcome. 🙂
Is there a way to add a download button to an audio file using CSS?
Not using CSS, but in the html, create a link for the audio and add the “download” attribute.
<a href="your/file" download>Download File</a>