user2451412 user2451412 - 3 months ago 5
CSS Question

Remove CSS transition, move the element, then re-apply it before moving it again

I'm having an issue with transitions.

I have a transition on the left property. I want to move a div from left: 860px to -860px without a transition, then move it to 0px with a transition.

If I remove the class giving the element the transition, apply a class that gives it -860px to the left, that's good. No transition.

However, since I want to apply a transition on it before I change left to 0px, I again add the transition class, and give it a class with left: 0. When I do this in Chrome it then applies the transition on the element on its way to the -860px position as well as to 0. So not what I want.

I want to avoid a delay between also. But I don't think there's an event that tells me when Chrome has re-rendered the element at -860px. Any ideas?

Here's some example code. The class with the transition:

.div-transition {
-webkit-transition:all 0.8s ease-in-out;
-moz-transition:all 0.8s ease-in-out;
-o-transition:all 0.8s ease-in-out;
transition:all 0.8s ease-in-out;

$(".div-to-transition").css('left', '-860px'); // So far so good, if I don't add the next two lines.
$(".div-to-transition").css('left', '0'); // Now it applies a transition as we move left to -860px, AND from -860px to 0.


Just repeating the comment: element.scrollWidth; after this line chrome should have re-rendered the element; without any waiting. or maybe element.getBoundingClientRect(); if chrome tries to be smart ;)

Understood. It's always a little scary to use something that is a side-effect rather than the intended purpose of an instruction. I guess I added both in case one of them gets optimized in a future version.

Although it's kind of abusing, it's less pure side-effect and more the implication of the nature of these properties and the nature of CSS.

Short answer long: You're asking the browser for a property of the node, that is influenced by the applied styles. Now the browser realizes that it has pending style-changes that need to be evaluated wether they have an impact on the property you're asking for. Through the cascade in CSS pretty much every style can influence almost every node on the page in some way.
For example by expanding the current node that much that the following node slides into the next row, wich now also affects it's style, ... and don't forget the parent-nodes and their successors.

So instead of trying to evaluate that mess, it's easier to apply all pending styles (wich basically means a re-rendeing of the whole page!) and then provide you the value you've asked for.

Even if you don't do anything with this value, and instead just asked to trigger this whole mechanism.

Since it now has again a stable state, the browser can provide you with all the properties you want without re-rendering, to the point where you change the style of some node again (or it's class).
//just saying: scrollWidth is not equal to re-rendering the whole page.

My first thought was simply that, chrome would maybe somehow be able to evaluate that you have not changed any property that influences dimension, of the node and therefore provide you an answer without the need to re-render the whole page, but as mentioned: in the mess that CSS is, that's almost impossible.

So if you want to be safe for the future, use only getBoundingClientRect(), wich explicitely asks for the computed position AND the computed dimensions of the node.