In response to the bounty:
If you don't have the luxury of knowing which property is being transitioned or simply don't think it's good practice to force a setTimeout to get an animation to fire, you can force a reflow in another way.
The reason that setTimeout works in the first place is due to the fact that you're causing a full document reflow in the meantime, even if the duration is set to 0. That's not the only way to cause a reflow.
JavaScript
for (x = Math.ceil(Math.random() * 10), i=0;i
$('
}
var divs = $('#container div');
var x = divs.eq(Math.ceil(Math.random() * divs.length));
x[0].offsetHeight;
x.addClass('wide');
With this JavaScript we're randomly adding between 1 and 10 div elements, and then selecting one of those at random and adding the wide class.
You'll notice an odd line of JavaScript in there, namely x[0].offsetHeight. This is the lynchpin to the whole operation. Calling offsetHeight triggers the document to reflow without using a setTimeout or querying the CSS value.
What a reflow is in relation to the DOM:
A reflow computes the layout of the page. A reflow on an element
recomputes the dimensions and position of the element, and it also
triggers further reflows on that element’s children, ancestors and
elements that appear after it in the DOM. Then it calls a final
repaint. Reflowing is very expensive, but unfortunately it can be
triggered easily.
So please be judicious in how you use these functions. Not too much of a concern with most modern browsers (as jQuery is notorious for firing several reflows), but still something to consider before adding something like this solution all over your website.
Important note: This is no more or less efficient than a setTimeout call. This isn't a magic bullet solution, and it's doing the same thing under the hood.
Here's the corresponding CSS, for reference:
.trans {
width: 20px;
height: 20px;
background-color: cyan;
-webkit-transition: all 5s ease;
-moz-transition: all 5s ease;
-o-transition: all 5s ease;
transition: all 5s ease;
}
.trans.wide {
width: 200px;
}