21

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?

Alejandro García Iglesias
  • 16,222
  • 11
  • 51
  • 64
Pherrymason
  • 7,835
  • 8
  • 39
  • 57

3 Answers3

22

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! :)

Community
  • 1
  • 1
Andy
  • 2,977
  • 2
  • 39
  • 71
  • @AlejandroIglesias The code above was modified from a jQuery plugin I wrote, so root is the root element that my plugin was applied to. – Andy Jun 19 '14 at 07:45
  • 1
    Beware of minification. Since the variable *reflow* isn't actually used anywhere a code minifier would likely just dispose of that line of code. Wrapping it in a void function may work better. ie. `void( root.offset().left )` – Octopus Aug 22 '18 at 21:01
  • This trick permitted my login page to repaint fully BEFORE the login button click event fired, which resolved a problem with a sticky tag that was hanging around during the login process. Like this: $(".reveal-eye-img").addClass("hidden"); var reflow = $(document.documentElement).offset().left; // Re-flow the page so the css changes get picked up and the eye is hidden $(".login-button-class").click(); – Allen Jul 17 '20 at 15:40
2

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]);
Jack G
  • 4,553
  • 2
  • 41
  • 50
  • 1
    This is for sure more readable than the original code, but just as a note, this is only a method wrapping the original code – Pherrymason Mar 29 '18 at 08:27
  • 1
    Correction: It is a bounded method wrapping the original code. Bounding the method prevents or explicitly tells (based on the complexity of the browser and its ability to optimize) the browser from performing dead code elimination on it – Jack G Mar 30 '18 at 03:43
0

it causes the webpage to reflow. because an element with display none style will not transition, it will force the web page to reflow after displaying to block so transition will take place.Ex bootstrap Modal