HTML onvolumechange Attribute

Beginner
⏱️ 6 min read
📚 Updated: Jun 2026
🎯 3 Examples
Events & Handlers

Introduction

The onvolumechange attribute is an inline event handler that runs JavaScript when the volumechange event fires on an audio or video element. It runs when the volume level or muted state changes — for example when the user drags the volume slider, clicks the mute button, or when your code sets media.volume or media.muted. Read media.volume (0.0 to 1.0) and media.muted inside the handler. Use it to sync custom volume sliders, show a volume percentage label, or save user preferences. Prefer addEventListener("volumechange", …) in production.

What You’ll Learn

01

Event handler

Inline JS.

02

volumechange

Volume or mute.

03

audio / video

Media only.

04

.volume

0.0 – 1.0.

05

Custom UI

Volume sliders.

06

addEventListener

Preferred way.

Purpose of onvolumechange Attribute

The primary purpose of onvolumechange is to react when volume or mute state changes — so your page can keep custom controls, labels, and saved preferences in sync with the actual media state, whether the user changed it from native controls or your JavaScript did.

The volumechange event fires on the media element whenever volume or muted changes. Default volume is 1 (100%). Video players, podcasts, and music sites often show a custom slider or percentage readout alongside native controls.

💡
Mute counts too

Clicking the mute button sets media.muted and also fires volumechange — one handler covers both volume slider and mute changes.

📝 Syntax

Set onvolumechange on audio or video, or assign media.onvolumechange in JavaScript:

onvolumechange.html
<audio controls onvolumechange="updateVolume()">
  <source src="/audio/count.mp3" type="audio/mpeg">
</audio>

<script>
  media.onvolumechange = updateVolume;
  media.addEventListener("volumechange", updateVolume);
</script>

Syntax Rules

  • Value is JavaScript executed when the volumechange event fires.
  • Valid on <audio> and <video> elements.
  • Read element.volume (0.0–1.0) and element.muted inside the handler.
  • Fires when the user adjusts native volume or mute or when you set volume / muted in code.
  • Also assignable as element.onvolumechange in script.
  • Modern alternative: media.addEventListener("volumechange", handler).
  • Not for non-media elements like input or div.

💎 Values

The onvolumechange attribute accepts a string of JavaScript code:

  • onvolumechange="updateVolume()" — Call a named function.
  • onvolumechange="status.textContent = Math.round(media.volume * 100) + '%'" — Inline update.
  • JavaScript: audio.onvolumechange = () => { … } — property assignment.
onvolumechange-handler.html
function updateVolume() {
  var pct = Math.round(media.volume * 100);
  status.textContent = media.muted
    ? "Muted"
    : "Volume: " + pct + "%";
  status.dataset.volume = String(media.volume);
}

media.addEventListener("volumechange", updateVolume);

⚡ Quick Reference

Property / eventWhen it firesNotes
volumechangeVolume or mute changesonvolumechange
media.volumeRead anytime0.0 = silent, 1.0 = full
media.mutedRead anytimetrue when muted
media.defaultMutedInitial mute stateSet via muted attribute
ratechangePlayback speed changesonratechange — different event

Applicable Elements

ElementSupported?Notes
<audio>YesPrimary use case
<video>YesSame volumechange event
<input type="range">RelatedCustom slider — sync with media.volume
<input>, <div>NoNot media elements
<iframe> (embed)NoCross-origin limits

onvolumechange vs setting volume vs onratechange

APIWhat it doesTypical use
onvolumechangeReact when volume or mute changesUpdate volume label / slider
media.volume = 0.5Set volume (fires volumechange)Custom volume controls
media.muted = trueMute (fires volumechange)Mute toggle button
onratechangePlayback speed changesSpeed label sync

Examples Gallery

Inline audio handler, dynamic assignment, and a custom volume slider with addEventListener.

👀 Live Preview

Adjust volume or mute on the audio controls — the label updates via volumechange:

Volume: 100%

Example — onvolumechange on audio

Display the new volume when the user adjusts the native controls:

audio-onvolumechange.html
<audio controls id="myMedia" onvolumechange="updateVolume()">
  <source src="/audio/count.mp3" type="audio/mpeg">
</audio>
<p id="status">Volume: 100%</p>

<script>
  function updateVolume() {
    var media = document.getElementById("myMedia");
    var pct = Math.round(media.volume * 100);
    document.getElementById("status").textContent =
      media.muted ? "Muted" : "Volume: " + pct + "%";
  }
</script>
Try It Yourself

How It Works

When volume or mute changes, the browser fires volumechange on the media element. The inline attribute runs updateVolume(), which reads volume and muted.

Dynamic Values with JavaScript

Assign the handler on the media element at runtime:

dynamic-onvolumechange.html
<script>
  media.onvolumechange = function () {
    log.textContent = this.muted
      ? "Audio muted"
      : "Volume: " + Math.round(this.volume * 100) + "%";
  };
</script>
Try It Yourself

How It Works

Assigning media.onvolumechange is equivalent to the inline attribute. Use this.volume and this.muted inside the function when assigned as a property handler.

Example — Custom volume slider

Set volume from a range input; volumechange keeps the UI synced when native controls change too:

volumechange-slider.html
slider.addEventListener("input", function () {
  media.volume = parseFloat(slider.value);
});

media.addEventListener("volumechange", function () {
  slider.value = String(media.volume);
  status.textContent = media.muted
    ? "Muted"
    : "Volume: " + Math.round(media.volume * 100) + "%";
});
Try It Yourself

How It Works

Setting volume programmatically fires volumechange, so a single listener handles both custom slider and native control changes without duplicating update logic.

♿ Accessibility

  • Label volume controls — Use aria-label on custom sliders like “Volume” or “Playback volume.”
  • Announce changes — Put the current volume in an element with aria-live="polite".
  • Do not hide native controls — Unless you rebuild them fully accessibly, keep browser media controls available.
  • Keyboard support — Custom volume sliders must be focusable; range inputs work with arrow keys by default.
  • Mute state — When muted, announce “Muted” clearly rather than showing 0% alone (volume may still be non-zero while muted).

🧠 How onvolumechange Works

1

Volume or mute changes

User or code.

volume / muted
2

volumechange fires

onvolumechange runs.

Event
3

Read .volume / .muted

Update UI.

Sync
=

Volume label

In sync.

Browser Support

The volumechange event and onvolumechange handler are supported in all modern browsers that support HTML5 media volume control.

Media Events · Fully supported

Universal onvolumechange support

All major browsers fire volumechange when volume or mute state changes.

99% Browser support
Google Chrome Fully supported
Full support
Mozilla Firefox Fully supported
Full support
Apple Safari Fully supported
Full support
Microsoft Edge Fully supported
Full support
Internet Explorer IE 9+ supported
Full support
Opera Fully supported
Full support
onvolumechange attribute 99% supported

Bottom line: Reliable for volume UI in all modern browsers.

💡 Best Practices

✅ Do

  • Use onvolumechange on audio / video
  • Read volume and muted inside the handler
  • Sync custom sliders via one volumechange listener
  • Use addEventListener("volumechange", …) in production
  • Show “Muted” when muted is true

❌ Don’t

  • Rely on console.log or alert() for user feedback
  • Put onvolumechange on non-media elements
  • Assume volume === 0 means muted (check muted too)
  • Duplicate UI updates in both slider input and volumechange handlers
  • Store volume as 0–100 in code without converting to 0.0–1.0 for media.volume

Conclusion

The onvolumechange attribute runs JavaScript when volume or mute state changes on audio or video — essential for keeping custom volume controls and labels in sync.

Read volume and muted in your handler, use one volumechange listener for both native and custom changes, and prefer addEventListener in production code.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about onvolumechange

Bookmark these before adding volume controls.

5
Core concepts
02

.volume

0.0 – 1.0.

API
🔇 03

.muted

Also fires.

Trigger
🆕 04

Volume slider

Custom UX.

Pattern
05

Not ratechange

Volume only.

Gotcha

❓ Frequently Asked Questions

It runs JavaScript when the volumechange event fires — when the volume or muted state of an audio or video element changes.
A number from 0.0 (silent) to 1.0 (full volume). Multiply by 100 for a percentage display. Default is 1.
Yes. Setting media.muted = true or clicking the mute button fires volumechange. Check media.muted in your handler — volume may still be non-zero while muted.
Yes. Assigning media.volume programmatically triggers the volumechange event, so your handler runs for both user and code changes.
media.addEventListener("volumechange", handler) is preferred in production — cleaner separation and multiple listeners if needed.
Yes in all modern browsers that support HTML5 audio and video volume control.

Build volume controls

Practice the onvolumechange attribute with inline handlers and custom volume sliders in the Try It editor.

Try onvolumechange demo →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful