How to Listen for CSS Transition End Events in jQuery

Listening for CSS transition end events in jQuery allows you to execute JavaScript callbacks immediately after a CSS animation finishes. This guide covers how to bind the standard transitionend event using jQuery's .on() and .one() methods, how to handle cross-browser vendor prefixes, and how to prevent callback issues caused by multiple transitioned properties.

The Basic Syntax

Modern browsers support the standard transitionend event. You can attach a listener to an element using jQuery's .on() method:

$('#myElement').on('transitionend', function(e) {
    console.log('Transition completed!');
});

Cross-Browser Support

To support older browsers that rely on vendor prefixes, list all variations separated by spaces within the event listener:

$('#myElement').on('transitionend webkitTransitionEnd oTransitionEnd', function() {
    $(this).addClass('active');
});

jQuery will automatically bind to whichever event the browser fires.

Firing the Callback Only Once with .one()

If an element transitions multiple CSS properties (such as opacity, transform, and width), the transitionend event fires once for every property that finishes. If you only want your callback to run once for the entire transition sequence, use .one() instead of .on():

$('#myElement').one('transitionend webkitTransitionEnd oTransitionEnd', function() {
    console.log('Fired only once, even if multiple properties transitioned.');
});

Filtering Specific CSS Properties

If an element has multiple transitions and you need to respond to a specific property's completion, inspect the propertyName on the original event object:

$('#myElement').on('transitionend', function(e) {
    if (e.originalEvent.propertyName === 'opacity') {
        console.log('Opacity transition finished.');
    }
});

Handling Event Bubbling

The transitionend event bubbles up the DOM tree. If a child element finishes a transition, the parent element will also receive the event. To ensure the event originated from the intended element, verify the event target:

$('#parentContainer').on('transitionend', function(e) {
    if (e.target === this) {
        console.log('Parent transition completed, ignoring child transitions.');
    }
});