"Force Reflow" in CSS transitions in Bootstrap
Revising the bootstrap-modal jquery plugin from Twitter's bootstrap I see that they use CSS transitions for the fading effect.
One thing that intrigues me from code is this line:
that.$element[0].offsetWidth // force reflow
If that line is commented transition doesn't work. All reference I've found about its meaning is that "force reflow" comment.
How reading that property can affect CSS transitions? Is this to address a bug in browsers?
Bit of a late reply, but I'm tackling some issues with CSS transitions which I think relate to this bit of code you've found, and hopefully help you out with understanding it!
Basically, I'm toggling a class from Javascript / jQuery that adds css transitions to a dom element. The CSS of this element is then updated which causes the transition to occur. A simplified version of the code is below:
var myelement = $("myselector");
// Set z-indexes before the transition
myelement.css("z-index", 1);
var reflow = root.offset().left; // Re-flow the page
// Set the transition class on the element which will animate
myelement.addClass("trans");
myelement.css("width", 0 + "px"); // Animate to nothing
So if I uncomment my re-flow line, my transition will occur, but sometimes (it seems more often in safari) the z-index of myelement won't have been updated.
To me, it seems that in certain situations, the styles written to the dom are being buffered somewhere and not being flushed.
That's where the call to the left offset comes in. This is one of the properties that are said to cause a re-flow in the page. This is obviously usually a bad thing performance wise, but it seems necessary to prevent the css transitions picking up the wrong values.
There's an interesting Mozilla bug lodged which discusses the same subject. Might be of some interest. They suggest the addition of an API to properly start transitions from code.
This is also an interesting SO post about forcing re-flows.
Hope this helps! :)
I would recommend a less hackish and more formal way to force a reflow: use forceDOMReflowJS. In your case, your code would look as follows.
forceReflowJS(that.$element[0]);