HTML onplay Attribute

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

Introduction

The onplay attribute is an inline event handler that runs JavaScript when the play event fires on an audio or video element. It runs when playback starts or resumes — by the user clicking play, pressing space, or when your code calls element.play(). Use it to show a “now playing” indicator, start animations, pause other media, or log analytics. Pair with onpause when playback stops. Prefer addEventListener("play", …) in production.

What You’ll Learn

01

Event handler

Inline JS.

02

play

Starts / resumes.

03

audio / video

Media only.

04

.play()

Programmatic.

05

+ onpause

Full UX pair.

06

addEventListener

Preferred way.

Purpose of onplay Attribute

The primary purpose of onplay is to react when media playback begins — so your page can update custom controls, show progress UI, sync lyrics or captions, pause background audio, or track that the user started listening or watching.

The play event fires on the media element when playback is initiated. It also fires when resuming after a pause. It is related to but not identical to playing, which fires once media is actually rendering frames or sound after buffering.

💡
Programmatic play counts too

Calling video.play() in JavaScript also fires the play event — your handler runs either way.

📝 Syntax

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

onplay.html
<audio controls onplay="startPlayback()" onpause="stopPlayback()">
  <source src="/audio/count.mp3" type="audio/mpeg">
</audio>

<script>
  media.onplay = startPlayback;
</script>

Syntax Rules

  • Value is JavaScript executed when the play event fires.
  • Valid on <audio> and <video> elements.
  • Also assignable as element.onplay in script.
  • Pair with onpause to update UI when playback stops.
  • Fires on first play and on resume after pause.
  • Modern alternative: media.addEventListener("play", handler).
  • Not for non-media elements like input or div.

💎 Values

The onplay attribute accepts a string of JavaScript code:

  • onplay="startPlayback()" — Call a named function.
  • onplay="status.textContent = 'Playing'" — Inline statement.
  • JavaScript: audio.onplay = () => { … } — property assignment.
onplay-handler.html
function startPlayback() {
  status.textContent = "Now playing";
  status.className = "status-playing";
  indicator.hidden = false;
}

audio.addEventListener("play", startPlayback);
audio.addEventListener("pause", stopPlayback);

⚡ Quick Reference

Property / eventWhen it firesNotes
playPlayback starts / resumesonplay
pausePlayback pausedonpause
playingAfter bufferingonplaying
media.play()Start via scriptAlso fires play
media.pausedAny time (read property)false when playing

Applicable Elements

ElementSupported?Notes
<audio>YesPrimary use case
<video>YesSame play event
<input>, <div>NoNot media elements
<iframe> (embed)NoCross-origin limits
Custom play buttonRelatedCall .play() on media

onplay vs onpause vs onplaying

AttributeEventTypical use
onplayplayShow playing state, start sync
onpausepauseHide indicator, save position
onplayingplayingAfter data is ready
onendedendedNext track, replay

Examples Gallery

Inline audio handler, addEventListener assignment, and custom play button.

👀 Live Preview

Play and pause the audio — status updates without an alert:

Ready — press play

Example — onplay on audio

Show feedback when playback starts:

audio-onplay.html
<audio controls onplay="startPlayback()" onpause="stopPlayback()">
  <source src="/audio/count.mp3" type="audio/mpeg">
</audio>
  <p id="status">Ready</p>

<script>
  function startPlayback() {
    document.getElementById("status").textContent = "Playing";
  }
  function stopPlayback() {
    document.getElementById("status").textContent = "Paused";
  }
</script>
Try It Yourself

How It Works

The browser fires play on the audio element when playback starts or resumes. The inline attribute runs startPlayback() at that moment.

Dynamic Values with JavaScript

Attach the handler with addEventListener:

dynamic-onplay.html
<audio controls id="myAudio">
  <source src="/audio/count.mp3" type="audio/mpeg">
</audio>

<script>
  document.getElementById("myAudio").addEventListener("play", function () {
    document.getElementById("log").textContent =
      "Playback started!";
  });
</script>
Try It Yourself

How It Works

addEventListener("play", …) is the preferred way to register the same handler as inline onplay.

Example — Custom play button

Call audio.play() — the play event still fires:

onplay-button.html
playBtn.addEventListener("click", function () {
  audio.play(); // triggers play event → onplay / listener runs
});

audio.addEventListener("play", function () {
  status.textContent = "Now playing via custom button";
});
Try It Yourself

How It Works

Custom players hide native controls but still rely on the media element’s play event for UI sync.

♿ Accessibility

  • Label custom play buttons — Use clear text like “Play audio” or aria-label.
  • Announce playing state — Use aria-live="polite" on status regions.
  • Do not autoplay with sound — Respect user preferences and browser autoplay policies.
  • Keyboard support — Custom buttons must be focusable and activatable with Enter/Space.
  • Provide captions — For video content when audio/dialog is important.

🧠 How onplay Works

1

Media idle

Paused / ready.

Idle
2

User plays

Click or .play().

Action
3

play fires

onplay runs.

Event
=

Update UI

Now playing.

Browser Support

The play event and onplay handler are supported wherever HTML5 audio and video are supported — all modern browsers.

Media Events · Fully supported

Universal onplay support

All major browsers fire play on audio and video elements.

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+ (media)
Full support
Opera Fully supported
Full support
onplay attribute 99% supported

Bottom line: Reliable for media play UX in all modern browsers.

💡 Best Practices

✅ Do

  • Pair onplay with onpause
  • Use addEventListener("play", …) in production
  • Handle .play() promise rejections (autoplay policy)
  • Use type="audio/mpeg" for MP3 sources
  • Pause other media when one starts (optional UX)

❌ Don’t

  • Use alert() when media starts
  • Confuse play with playing events
  • Put onplay on non-media elements
  • Autoplay sound without user gesture
  • Assume play means frames are rendering — check playing too

Conclusion

The onplay attribute runs JavaScript when audio or video playback starts or resumes — essential for custom players, status UI, and synced page effects.

Pair it with onpause, handle programmatic .play(), and prefer addEventListener in production code.

Key Takeaways

Knowledge Unlocked

Five truths every developer should know about onplay

Bookmark these before building custom media players.

5
Core concepts
🔄 02

+ onpause

Pair both.

Pattern
🔎 03

.play()

Script too.

API
🎧 04

Resume

After pause.

UX
05

Not playing

See onplaying.

Gotcha

❓ Frequently Asked Questions

It runs JavaScript when the play event fires — when audio or video playback starts or resumes.
<audio> and <video> — HTML5 media elements only.
Yes. The play event fires both on first play and when resuming from a paused state.
play fires when playback is requested. playing fires when media is actually outputting after buffering.
media.addEventListener("play", handler) is preferred for production code.
Yes in all browsers with HTML5 audio and video support.

Build responsive media players

Practice the onplay attribute with audio play examples in the Try It editor.

Try onplay 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