Is it possible to get a notification (like callback) when a CSS transition has been completed?
-
http://stackoverflow.com/questions/5023514/how-do-i-normalize-css3-transition-functions-across-browsers – zloctb Mar 06 '15 at 11:52
5 Answers
Yes, if such things are supported by the browser, then an event is triggered when the transition completes. The actual event however, differs between browsers:
- Webkit browsers (Chrome, Safari) use
webkitTransitionEnd
- Firefox uses
transitionend
- IE9+ uses
msTransitionEnd
- Opera uses
oTransitionEnd
However you should be aware that webkitTransitionEnd
doesn't always fire! This has caught me out a number of times, and seems to occur if the animation would have no effect on the element. To get around this, it makes sense to use a timeout to fire the event handler in the case that it's not been triggered as expected. A blog post about this problem is available here: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <-- 500 Internal Server Error
With this in mind, I tend to use this event in a chunk of code that looks a bit like this:
var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd"..
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function(){
done = true;
//do your transition finished stuff..
elemToAnimate.removeEventListener(transitionEndEventName,
transitionEnded, false);
};
elemToAnimate.addEventListener(transitionEndEventName,
transitionEnded, false);
//animation triggering code here..
//ensure tidy up if event doesn't fire..
setTimeout(function(){
if(!done){
console.log("timeout needed to call transition ended..");
transitionEnded();
}
}, XXX); //note: XXX should be the time required for the
//animation to complete plus a grace period (e.g. 10ms)
Note: to get the transition event end name you can use the method posted as the answer in: How do I normalize CSS3 Transition functions across browsers?.
Note: this question is also related to: - CSS3 transition events

- 1
- 1

- 10,049
- 4
- 48
- 51
-
2This is a much fuller answer than the accepted one. Why isn't this more upvoted. – Wes Jun 23 '13 at 09:29
-
Remember to call `transitionEndedHandler` in `transitionEnded` (or change `transitionEnded` by `transitionEndedHandler` in `addEventListener` and `removeEventListener` and call `transitionEnded` in `transitionEndedHandler`) – Miquel Jan 31 '15 at 13:52
-
Thanks @Miquel; think I'd just used `transitionEnded` when I meant `transitionEndedHandler`. – Mark Rhodes Jan 31 '15 at 18:31
-
I believe the Chromium issue for this can be found here: https://code.google.com/p/chromium/issues/detail?id=388082 Although, the last comment seems to (incorrectly in my view) discount it as a bug and therefore it is currently marked as "won't fix". – Willster Jun 11 '15 at 14:47
-
1No need for different names nowadays https://caniuse.com/#feat=css-transitions – Ruan Mendes Feb 21 '20 at 12:41
I know that Safari implements a webkitTransitionEnd callback that you can attach directly to the element with the transition.
Their example (reformatted to multiple lines):
box.addEventListener(
'webkitTransitionEnd',
function( event ) {
alert( "Finished transition!" );
}, false );

- 37,241
- 25
- 195
- 267

- 65,509
- 13
- 109
- 118
-
-
7
-
2
-
@meo It has something to do with the `this` element inside the callback. But its a required parameter, so in this case its just fulfilling the requirement. – Doug Neiner Mar 19 '11 at 17:23
-
9@DougNeiner The false at the end is for `useCaptureMode`. When an event occurs, there are two phases - the first phase is capture mode, the second is bubble mode. In capture mode, the event descends from the body element to the specified element. It then enters bubble mode, where it does the reverse. That final false param specifies that you want the event listener to occur in bubble mode. One use of this is to attach event handlers right before they are needed in bubble mode. =) http://37signals.com/svn/posts/3137-using-event-capturing-to-improve-basecamp-page-load-times – rybosome Jul 29 '12 at 18:31
-
I am using the following code, is much simpler than trying to detect which specific end event a browser uses.
$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd',
function() {
//do something
});
Alternatively if you use bootstrap then you can simply do
$(".myClass").one($.support.transition.end,
function() {
//do something
});
This is becuase they include the following in bootstrap.js
+function ($) {
'use strict';
// CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
// ============================================================
function transitionEnd() {
var el = document.createElement('bootstrap')
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd otransitionend',
'transition' : 'transitionend'
}
for (var name in transEndEventNames) {
if (el.style[name] !== undefined) {
return { end: transEndEventNames[name] }
}
}
return false // explicit for ie8 ( ._.)
}
// http://blog.alexmaccaw.com/css-transitions
$.fn.emulateTransitionEnd = function (duration) {
var called = false, $el = this
$(this).one($.support.transition.end, function () { called = true })
var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
setTimeout(callback, duration)
return this
}
$(function () {
$.support.transition = transitionEnd()
})
}(jQuery);

- 12,591
- 13
- 72
- 112
-
2This is slower because it has to search through that entire list each time the event happens to see if it is the correct one. – phreakhead Feb 13 '14 at 07:07
-
3@phreakhead The performances of any of these approaches will be very similar – Tom May 13 '14 at 15:31
This can easily be achieved with the transitionend
event. See documentation here.
A simple example:
document.getElementById("button").addEventListener("transitionend", myEndFunction);
function myEndFunction() {
this.innerHTML = "Transition event ended";
}
#button {transition: top 2s; position: relative; top: 0;}
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

- 11,722
- 5
- 72
- 103

- 3,378
- 3
- 29
- 38
-
5This is the correct answer nowadays, there's no need to have prefixes anymore. https://caniuse.com/#feat=css-transitions – Ruan Mendes Feb 21 '20 at 12:42
-
1or https://developer.mozilla.org/en-US/docs/Web/API/Element/transitionend_event#browser_compatibility – djvg Mar 30 '23 at 13:45
The jQuery.transit plugin, a plugin for CSS3 transformations and transitions, can call your CSS animations from script and give you a callback.

- 11,385
- 7
- 52
- 75

- 2,819
- 4
- 24
- 30