JavaScript Element transitionrun Event

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

What You’ll Learn

The transitionrun event fires when a CSS transition is first created—before any transition-delay has begun. Learn how it differs from transitionstart, addEventListener vs ontransitionrun, TransitionEvent properties, and five try-it labs.

01

Kind

Instance event

02

Type

TransitionEvent

03

When

Transition created

04

Handler

ontransitionrun

05

Cancelable?

No

06

Status

Baseline Widely

Introduction

As soon as the browser creates a CSS transition, it fires transitionrun—even if a delay means the element has not started moving yet. Think of it as “the transition is scheduled / running in the delay window,” not “pixels are already changing.”

After the delay ends, you get transitionstart when motion actually begins. If someone cancels during the delay, you may still have seen transitionrun, then transitioncancel instead of start/end.

💡
Beginner tip

With no delay (or a negative delay), MDN says both transitionrun and transitionstart fire. A positive delay is the easiest way to see them as two separate moments.

Understanding transitionrun

An instance event on elements that participate in CSS Transitions. MDN: it fires when a CSS transition is first created, i.e., before any transition-delay has begun. It is not cancelable.

  • Created at the start of any delay—motion may not have started yet.
  • TransitionEvent — includes propertyName, elapsedTime, pseudoElement.
  • Still fires if the transition is canceled before the delay expires.
  • Baseline Widely available — solid modern browser support (since Mar 2020).

📝 Syntax

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

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

ontransitionrun = (event) => { };

Event type

A TransitionEvent (inherits from Event).

Event properties

PropertyMeaning
propertyNameThe CSS property name associated with the transition
elapsedTimeSeconds the transition had been running when the event fired (not affected by transition-delay)
pseudoElement:: name if the transition runs on a pseudo-element; otherwise ""

⚖️ transitionrun vs related events

EventWhen it firesTypical use
transitionrunTransition is created (start of any delay)Mark “scheduled / pending delay”
transitionstartActual animation begins (end of any delay)Mark UI as “in motion”
transitionendTransition finishes normallyCleanup after success
transitioncancelTransition is aborted earlyCleanup after interrupt

MDN’s key contrast: transitionrun = created / delay starts; transitionstart = delay over, pixels moving.

⚡ Quick Reference

GoalCode
Listenel.addEventListener("transitionrun", fn)
Handler propertyel.ontransitionrun = fn
See run before startUse a positive transition-delay
Read propertyevent.propertyName
Cancelable?No
MDN statusBaseline Widely available

🔍 At a Glance

Four facts to remember about transitionrun.

Event type
TransitionEvent

Property + time

Means
created

Before delay ends

Cancelable
false

Observe only

Baseline
yes

Widely available

Examples Gallery

Examples follow MDN Element: transitionrun event. Try It Yourself labs use a delay so you can see transitionrun before motion starts.

📚 Getting Started

Register handlers the MDN ways when a transition is created.

Example 1 — addEventListener("transitionrun")

MDN: the transition is running but has not necessarily started transitioning yet.

JavaScript
const el = document.querySelector(".transition");

el.addEventListener("transitionrun", () => {
  console.log(
    "Transition is running but hasn't necessarily started transitioning yet"
  );
});

el.classList.add("grown");
Try It Yourself

How It Works

Adding the driving class creates the transition immediately. With a positive delay, this log appears before the box starts moving.

Example 2 — ontransitionrun Property

MDN’s alternate style using the event handler property.

JavaScript
const el = document.querySelector(".transition");

el.ontransitionrun = () => {
  console.log(
    "Transition started running, and will start transitioning when the transition delay has expired"
  );
};

el.classList.add("grown");
Try It Yourself

How It Works

Same event, different registration API. Prefer addEventListener when you need multiple listeners or easy removal.

📈 Details, Delay Gap & Lifecycle

Read TransitionEvent fields, compare with start, watch the full set.

Example 3 — Read propertyName and elapsedTime

Use TransitionEvent properties for logging or debugging.

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

box.addEventListener("transitionrun", (event) => {
  console.log("run:", event.propertyName);
  console.log("elapsedTime:", event.elapsedTime);
  console.log("pseudoElement:", JSON.stringify(event.pseudoElement));
});

box.classList.add("grown");
Try It Yourself

How It Works

At creation time elapsedTime is often near 0. Multiple properties may each produce their own transitionrun.

Example 4 — transitionrun vs transitionstart

With a delay, run fires first; start fires when motion actually begins.

JavaScript
const el = document.querySelector(".transition");
const message = document.querySelector(".message");

el.addEventListener("transitionrun", () => {
  message.textContent = "transitionrun fired";
});
el.addEventListener("transitionstart", () => {
  message.textContent = "transitionstart fired";
});

el.classList.add("grown");
// CSS: transition-delay: 1s; → run now, start ~1s later
Try It Yourself

How It Works

This is MDN’s core teaching demo: delay makes the gap visible. Cancel during the delay and you may never see transitionstart.

Example 5 — Full Lifecycle Log

Log run, start, cancel, and end together (class toggle with delay).

JavaScript
const el = document.querySelector(".transition");
const message = document.querySelector(".message");
const btn = document.getElementById("toggle");

el.addEventListener("transitionrun", () => {
  message.textContent = "transitionrun fired";
});
el.addEventListener("transitionstart", () => {
  message.textContent = "transitionstart fired";
});
el.addEventListener("transitioncancel", () => {
  message.textContent = "transitioncancel fired";
});
el.addEventListener("transitionend", () => {
  message.textContent = "transitionend fired";
});

btn.addEventListener("click", () => {
  el.classList.toggle("grown");
});
Try It Yourself

How It Works

Toggle on and watch the message flip from run → start → end. Toggle off during the delay to practice cancel after run.

🚀 Common Use Cases

  • Showing a “pending” UI state as soon as a delayed transition is scheduled.
  • Debugging delay timing vs when motion actually starts.
  • Analytics that count created transitions (including ones canceled in delay).
  • Teaching the full CSS transition event set with a clear delay gap.
  • Coordinating work that must begin at creation time, not after delay.

🔧 How It Works

1

Style change creates a transition

Class toggle, hover, or property change schedules a CSS transition.

Create
2

Browser fires transitionrun

Before delay begins—transition exists even if motion has not started.

Event
3

Delay ends → transitionstart

Or cancel during delay → transitioncancel (run already happened).

Next
4

Your handler reacts early

Update pending UI, log scheduling, or prepare for motion / cancel.

📝 Notes

  • MDN: Baseline Widely available (since March 2020).
  • Not Deprecated, Experimental, or Non-standard — no status banner required.
  • Not cancelable; observe with addEventListener.
  • Fires even if canceled before delay expires; zero delay makes run and start fire together.
  • Related learning: transitionend, transitioncancel, addEventListener(), JavaScript hub.

Browser Support

transitionrun is marked Baseline Widely available on MDN (across browsers since March 2020). Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

Element transitionrun

Fires when a CSS transition is first created, before any transition-delay. Not cancelable. Pair with transitionstart to see the delay gap.

Full Widely available
Google Chrome 74+
Yes
Mozilla Firefox 53+
Yes
Apple Safari 13.1+
Yes
Microsoft Edge 79+ Chromium (legacy Edge partial)
Yes
Opera 62+
Yes
Internet Explorer No transitionrun support
Unavailable
transitionrun Baseline

Bottom line: Listen with addEventListener("transitionrun", …). Use a positive delay to separate it from transitionstart; expect run even if cancel happens during delay.

Conclusion

transitionrun is the earliest CSS transition lifecycle signal—the transition was created, even if delay means motion has not started. Pair it with transitionstart, transitionend, and transitioncancel for a complete picture.

Continue with transitionstart, transitionend, or the JavaScript hub.

💡 Best Practices

✅ Do

  • Use addEventListener("transitionrun", ...)
  • Use a positive delay when teaching run vs start
  • Handle cancel paths that can follow run during delay
  • Log propertyName when several properties transition
  • Keep handlers light—this can fire often on busy UIs

❌ Don’t

  • Assume transitionrun means pixels are already moving
  • Expect only one event when multiple properties transition
  • Forget that zero/negative delay makes run and start fire together
  • Confuse this with CSS Animations / Web Animations APIs
  • Skip transitionstart if you need “motion began”

Key Takeaways

Knowledge Unlocked

Five things to remember about transitionrun

Transition created—before delay ends, before motion starts.

5
Core concepts
🎨 02

TransitionEvent

property + time

API
⏱️ 03

vs start

delay gap

Compare
🔔 04

addEventListener

preferred

Listen
🎯 05

Baseline

widely available

Compat

❓ Frequently Asked Questions

It fires when a CSS transition is first created — that is, before any transition-delay has begun. The transition may still be waiting in its delay period. It is not cancelable.
No. MDN does not mark Element transitionrun as Deprecated, Experimental, or Non-standard. It is Baseline Widely available (across browsers since March 2020).
transitionrun fires when the transition is created (start of any delay). transitionstart fires when the actual animation begins (end of any delay). With no delay or a negative delay, both fire.
A TransitionEvent. Useful read-only properties include propertyName, elapsedTime, and pseudoElement.
Prefer element.addEventListener("transitionrun", handler). You can also set ontransitionrun where supported.
Yes. MDN notes transitionrun still occurs even if the transition is canceled before the delay expires — then you typically see transitioncancel instead of transitionstart/transitionend.
Did you know?

If you cancel during the delay window, you can see transitionrun without ever seeing transitionstart or transitionend—then transitioncancel cleans up the aborted schedule.

Next: transitionstart

Learn when a CSS transition actually starts after delay.

transitionstart →

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