I was reading this article http://semisignal.com/?p=5298 and the author wrote that
"Reflow needs to be triggered before the invisible class is removed in order for the transition to work as expected. "
My questions are :
1) Why does reflow need to be triggered?
2) I understand that we should avoid using reflow, if that is true why is the author suggesting to use reflow in order to make the transition work?
3) Instead of using reflow, is there a different method to make the transition work?
Thank you.
(Effectively: "Why can't I easily use transitions with the
display
property")Short Answer:
CSS Transitions rely on starting or static properties of an element. When an element is set to
display: none;
the document (DOM) is rendered as though the element doesn't exist. This means when it's set todisplay: block;
- There are no starting values for it to transition.Longer Answer:
display: none;
are not drawn in the document yet. This prevents transitions from having a starting value/initial state. Setting an element todisplay: none;
makes the document render as if the element isn't there at all.display: none;
anddisplay: block;
- typically after the element has been requested by an action (tab or button click, callback function, timeout function, etc.). Transitions are a huge bonus to UX, so reflowing is a relatively simple way to allow these transitions to occur. It doesn't have an enormous impact when you use simple transitions on simple sites, so for general purposes you can trigger a reflow, even if technically you shouldn't. Think of the guy's example like using unminified JavaScript files in a production site. Can you? Sure! Should you? Probably not, but for most cases, it won't make a hugely noticeable difference.A: This element is set to
height: 0;
andoverflow: hidden;
. When shown, it's set toheight: auto;
. We apply the animation to only theopacity
. This gives us a similar effect, but we can transition it without a reflow because it's already rendered in the document and gives the transitions initial values to work with.B: This element is the same as A, but sets the height to a defined size.
A and B work well enough for fading in elements, but because we set the height from
auto/100px
to0
instantly, they appear to collapse on "fade out"C: This element is hidden and we attempt to transition the child. You can see that this doesn't work either and requires a reflow to be triggered.
D: This element is hidden and we animate the child. Since the animation keyframes give a defined starting and ending value, this works much better. However note that the black box snaps into view because it's still attached to the parent.
E: This works similarly to D but we run everything off the child, which doesn't solve our "black box" issue we had with D.
F: This is probably the best of both worlds solution. We move the styling off the parent onto the child. We can trigger the animation off of the parent, and we can control the
display
property of the child andanimate
the transition as we want. The downside to this being you need use animation keyframes instead of transitions.G: While I don't know if this triggers a reflow inside the function as I haven't parsed it myself, you can just simply use jQuery's
.fadeToggle()
function to accomplish all of this with a single line of JavaScript, and is used so often (or similar JS/jQuery fadeIn/fadeOut methods) that the subject of reflowing doesn't come up all that often.Examples:
Here's a CodePen: https://codepen.io/xhynk/pen/gerPKq
Here's a Snippet: