JavaScript Element animationstart Event

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
DOM event
Instance event

What You’ll Learn

The animationstart event fires when a CSS Animation begins. Learn addEventListener vs onanimationstart, how animation-delay (including negative delay) affects elapsedTime, and how it leads into animationiteration / animationend—with five examples and try-it labs.

01

Kind

Instance event

02

Type

AnimationEvent

03

When

Animation begins

04

Handler

onanimationstart

05

Delay

Fires after delay

06

Status

Baseline widely available

Introduction

As soon as a CSS animation is ready to play—after any positive animation-delay—the browser fires animationstart. Use it to mark UI as “playing,” disable a button, or prepare the next step in a motion sequence.

MDN: with a negative delay, the event still fires, and elapsedTime equals the absolute value of the delay. The animation begins partway through its keyframes, as if it had already been running.

💡
Beginner tip

Prefer addEventListener("animationstart", ...) so you can attach multiple handlers and remove them cleanly. The onanimationstart property is fine for quick demos.

Understanding animationstart

An instance event on elements that begin a CSS Animation. It answers: “Has this animation started playing?”

  • Fires when the animation starts (after a positive delay, if any).
  • elapsedTime is usually 0; with negative delay it is -1 * delay.
  • AnimationEvent — includes animationName, elapsedTime, pseudoElement.
  • Baseline Widely available on MDN (since December 2019).

📝 Syntax

Use the event name with addEventListener, or set the handler property:

JavaScript
addEventListener("animationstart", (event) => { });

onanimationstart = (event) => { };

Event type

An AnimationEvent (inherits from Event).

Event properties

PropertyMeaning
animationNameThe animation-name that generated the animation
elapsedTimeUsually 0 at start; with negative delay, -1 * delay
pseudoElement:: name if animated on a pseudo-element; otherwise ""

⏱️ animation-delay and elapsedTime

DelayWhen animationstart fireselapsedTime
0s (default)Immediately when the animation applies0
Positive (e.g. 1s)After the delay expires0
Negative (e.g. -0.5s)When the animation applies (starts mid-sequence)0.5 (-1 * delay)

⚖️ Animation lifecycle events

EventWhen it firesTypical use
animationstartAnimation beginsMark UI as “playing”
animationiterationEach loop ends and the next beginsCount loops
animationendEntire animation finishesCleanup after success
animationcancelAnimation aborts earlyCleanup after interrupt

⚡ Quick Reference

GoalCode / note
Listenel.addEventListener("animationstart", fn)
Handler propertyel.onanimationstart = fn
Read nameevent.animationName
Read timeevent.elapsedTime
Positive delayEvent waits until delay ends; elapsedTime still 0
Negative delayelapsedTime = -1 * delay
MDN statusBaseline Widely available (Dec 2019)

🔍 At a Glance

Four facts to remember about animationstart.

Event type
AnimationEvent

Name + time

Means
begun

Playback starts

Default time
0

Unless neg. delay

Baseline
yes

Widely available

Examples Gallery

Examples follow MDN Element: animationstart event. Try It Yourself labs start a CSS animation so you can watch the event fire—including delay cases.

📚 Getting Started

Register handlers the MDN ways.

Example 1 — addEventListener("animationstart")

MDN: listen and log when the animation starts.

JavaScript
const animated = document.querySelector(".animated");

animated.addEventListener("animationstart", () => {
  console.log("Animation started");
});
Try It Yourself

How It Works

As soon as the CSS animation is applied and any positive delay has passed, the handler runs once for that start.

Example 2 — onanimationstart Property

MDN’s alternate style using the event handler property.

JavaScript
const animated = document.querySelector(".animated");

animated.onanimationstart = () => {
  console.log("Animation started");
};

// Assigning again replaces the previous onanimationstart handler.
Try It Yourself

How It Works

Same event, different registration API. Prefer addEventListener when you need more than one handler.

📈 Details, Delay & Lifecycle

Read AnimationEvent fields, compare delay behavior, watch the full set.

Example 3 — Read animationName and elapsedTime

Inspect AnimationEvent properties at start time.

JavaScript
const box = document.getElementById("box");

box.addEventListener("animationstart", (event) => {
  console.log("name:", event.animationName);
  console.log("elapsedTime:", event.elapsedTime);
  console.log("pseudoElement:", JSON.stringify(event.pseudoElement));
});

box.classList.add("fade-in");
Try It Yourself

How It Works

Without a negative delay, elapsedTime is 0 at animationstart. Filter by animationName when several animations share one element.

Example 4 — Positive vs Negative animation-delay

Compare when the event fires and what elapsedTime reports.

JavaScript
const delayed = document.getElementById("delayed");
const skipped = document.getElementById("skipped");

function logStart(el, label) {
  el.addEventListener("animationstart", (event) => {
    console.log(label + " start, elapsedTime:", event.elapsedTime);
  });
}

logStart(delayed, "delay+0.4s");
logStart(skipped, "delay-0.4s");

delayed.classList.add("run-delayed"); // animation-delay: 0.4s
skipped.classList.add("run-skipped"); // animation-delay: -0.4s
Try It Yourself

How It Works

The negative-delay animation starts immediately (mid-sequence) with a non-zero elapsedTime. The positive-delay animation waits, then starts with elapsedTime: 0.

Example 5 — Full Lifecycle Log

Inspired by MDN’s live example: log start, iteration, end, and cancel together.

JavaScript
const el = document.querySelector("p.animation");
const log = document.getElementById("log");
const btn = document.getElementById("toggle");
let iterations = 0;

function append(msg) {
  log.textContent += msg + " ";
}

el.addEventListener("animationstart", () => append("start"));
el.addEventListener("animationiteration", () => {
  iterations += 1;
  append("iteration:" + iterations);
});
el.addEventListener("animationend", () => {
  append("end");
  el.classList.remove("active");
  btn.textContent = "Activate animation";
});
el.addEventListener("animationcancel", () => append("canceled"));

btn.addEventListener("click", () => {
  el.classList.toggle("active");
  log.textContent = "";
  iterations = 0;
  const on = el.classList.contains("active");
  btn.textContent = on ? "Cancel animation" : "Activate animation";
});
Try It Yourself

How It Works

animationstart is always first. Then optional iteration events, then animationend—unless you cancel mid-run.

🚀 Common Use Cases

  • Disabling a “Play” button while an entrance animation runs.
  • Showing a “playing” badge or spinner when motion begins.
  • Analytics: count how often a branded animation actually starts.
  • Coordinating audio or captions with the first frame after delay.
  • Teaching the CSS animation lifecycle next to iteration/end/cancel.

🔧 How It Works

1

Animation is applied

Class, style, or stylesheet starts a named animation.

Apply
2

Delay resolves

Positive delay waits; negative delay skips ahead.

Timing
3

Browser fires animationstart

An AnimationEvent is dispatched.

Event
4

Your handler reacts

Update UI, then wait for iteration/end/cancel as needed.

📝 Notes

  • MDN: Baseline Widely available (since December 2019).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Positive animation-delay postpones the event until the delay ends.
  • Negative delay sets a non-zero elapsedTime at start.
  • Related learning: animationiteration, animationend, animationcancel, JavaScript hub.

Universal Browser Support

animationstart is marked Baseline Widely available on MDN (since December 2019). Logos use the shared browser-image-sprite.png sprite from this project. Pair it with animationend and animationiteration for full lifecycle handling.

Baseline · Widely available

Element animationstart

Works across modern desktop and mobile browsers when a CSS animation begins.

100% Widely available
Google Chrome Supported · Desktop & Android
Full support
Mozilla Firefox Supported · Desktop & Android
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Opera Supported · Modern versions
Full support
Internet Explorer Legacy support with prefixes in older IE
Partial
animationstart Baseline

Bottom line: Safe to use for UI that reacts when a CSS animation begins. Remember delay changes when the event fires and what elapsedTime reports.

Conclusion

animationstart is the “playback began” signal for CSS Animations. Listen with addEventListener, account for delays in timing and elapsedTime, then pair with iteration/end/cancel for the full story.

Continue with auxclick, addEventListener(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Prefer addEventListener("animationstart", ...)
  • Check event.animationName when multiple animations share a node
  • Account for positive delays before expecting the event
  • Read elapsedTime when using negative delays
  • Also handle animationend / animationcancel for cleanup

❌ Don’t

  • Assume the event fires before a positive delay ends
  • Assume elapsedTime is always zero
  • Confuse CSS animationstart with Web Animations API play events
  • Overwrite onanimationstart if you need multiple listeners
  • Forget infinite animations never fire animationend

Key Takeaways

Knowledge Unlocked

Five things to remember about animationstart

The CSS animation has begun—update UI and watch the lifecycle.

5
Core concepts
🎬 02

AnimationEvent

name + time

API
⏱️ 03

Respect delay

wait or skip

Timing
🔔 04

addEventListener

preferred

Listen
🎯 05

Baseline

widely available

Compat

❓ Frequently Asked Questions

It fires when a CSS Animation has started. If there is an animation-delay, the event fires after that delay expires. With a negative delay, the event still fires and elapsedTime equals the absolute value of the delay.
No. MDN marks Element animationstart as Baseline Widely available (since December 2019). It is not Deprecated, Experimental, or Non-standard.
An AnimationEvent. Useful read-only properties include animationName, elapsedTime, and pseudoElement.
Use element.addEventListener("animationstart", handler) or set element.onanimationstart = handler. Prefer addEventListener when you need multiple handlers or easy removal.
Usually 0.0. If animation-delay is negative, elapsedTime is (-1 * delay) — for example a delay of -0.5s yields elapsedTime 0.5, and the animation begins partway through its sequence.
animationstart is first. Then you may get animationiteration between loops, animationend when the full run completes, or animationcancel if the animation aborts early.
Did you know?

Negative animation-delay is a common trick to start an infinite spinner or carousel “already in motion.” animationstart still fires, but elapsedTime tells you how far into the timeline you jumped.

Next: auxclick

Learn middle-click, right-click, and other non-primary button events.

auxclick →

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