JSFiddle - React, Tailwind, and code Playground

HTML

<div>
    <p></p>
    <section>
         <h1>h1</h1>

    </section>
     <h2>h2</h2>

</div>

CSS

p {
    opacity: 0;
    transition: opacity 10s, transform 5s;
    background: red;
    width: 50px;
    height: 50px;
    margin: 100px;
}
div.visible p {
    opacity: 1;
    transform: scale(1.5);
}
h1 {
    color: purple;
    transition: color 5s 2s, padding 3s 4s;
}
div.visible h1 {
    padding: 25px 0;
    color: gold;
}
div {
    display: inline-block;
    transition: transform 1s;
    width: 100px;
    height: 100px;
    background: blue;
}
div.visible {
    transform: translate(20px, 20px);
}

JavaScript

(function ($) {

    $.event.special.transitionsComplete = {

        setup: function (data, namespaces, eventHandle) {
            var TRANSITION_PROPERTY = 'transition-property';
            var TRANSITION_DURATION = 'transition-duration';

            var root = this;
            var queue = [];
            var $node = $(this);

            function filter(node) { // filter for treeWalker
                /*** filters transitions which are a string with one '0s'. If more then '0s' is defined it will be catched when creating the queue ***/
                var computedDuration = window.getComputedStyle(node, null)
                    .getPropertyValue(TRANSITION_DURATION);

                return computedDuration === '0s' ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
            }

            filter.acceptNode = filter; // for webkit and firefox

            /** create the treeWalker to traverse only elements **/
            var treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, filter, false);

            /** traverse all elements using treeWalker.nextNode(). First node is the root **/
            do {
                var style = window.getComputedStyle(treeWalker.currentNode, null);
                var computedProps = style.getPropertyValue(TRANSITION_PROPERTY).split(', ');
                var computedDurations = style.getPropertyValue(TRANSITION_DURATION).split(', ');

                /** push all props with duration which is not 0s **/
                computedDurations.forEach(function (duration, index) {
                    duration !== '0s' && queue.push(computedProps[index]);
                });
            } while (treeWalker.nextNode()); // iterate until no next node

            console.log('transitions', queue);

            // no transitions, fire (almost) immediately
            if (queue.length === 0) {

                setTimeout(function () {
                    console.log('No transitions - Transitions Complete');
    ...