I want to bypass CSS transition and change a property instantly.
I tried to set transition-duration
to 0s
before the change and then set transition-duration
back to its original value:
$('div').css('width', '200px').delay(1000).queue(function() { $(this).css({ transitionDuration: '0s', msTransitionDuration: '0s', mozTransitionDuration: '0s', webkitTransitionDuration: '0s', oTransitionDuration:'0s' }).css('width', '10px').css({ transitionDuration: '2s', msTransitionDuration: '2s', mozTransitionDuration: '2s', webkitTransitionDuration: '2s', oTransitionDuration:'2s' }) })
Fiddle
This obviously doesn't work.
I understand that the spec does not define that behavior for this:
Since this specification does not define when computed values change, and thus what changes to computed values are considered simultaneous, authors should be aware that changing any of the transition properties a small amount of time after making a change that might transition can result in behavior that varies between implementations, since the changes might be considered simultaneous in some implementations but not others.
Is there an easy way to do this?
Note: The property I am changing is transform
so .animate()
would not be an option.
transition properties allow elements to change values over a specified duration, animating the property changes, rather than having them occur immediately.
The transition effect will start when the specified CSS property (width) changes value.
Transitioning two or more propertiesYou can transition two (or more) CSS properties by separating them with a comma in your transition or transition-property property. You can do the same with duration, timing-functions and delays as well. If the values are the same, you only need to specify one of them.
When we want to use transition for display:none to display:block, transition properties do not work. The reason for this is, display:none property is used for removing block and display:block property is used for displaying block. A block cannot be partly displayed. Either it is available or unavailable.
Since nobody else is posting a valid answer, here goes:
$('div').css('width', '200px').delay(1000).queue(function() { $(this).css({transition: '0s', width: '10px'}).delay(1).queue(function() { $(this).css({transition:'2s'}); }); },1000);
FIDDLE
Or if it's the other way:
$('div').css({ transition: '0s' }).css('width', '200px').delay(1000).queue(function() { $(this).css({width: '10px', transition: '2s'}); });
FIDDLE
jQuery should normalize vendor prefixes these days, so you don't have to type them all yourself.
The issue here is that jQuery attaches all the styles at once, only keeping the last styles, overwriting the previous styles of the same CSS property without ever doing a repaint of the DOM, and testing with native javascript seems to be doing the same thing, so it's probably the browser trying to avoid uneccessary reflows by adding a style just to have it changed in the next line of code, so doing:
$('div').css({ transition: '0s', width: 200 }).css({ transition: '3s', width: 10 });
won't work as only the last style is added.
This is where delay()
comes into play, the OP's question was already using delay()
so there was no reason not to use it, but removing delay()
will of course cause the above issue, where the browser doesn't paint the first style, but only the last etc.
As delay()
is really just a fancy timeout, it effectively defers the execution of the second setting of the styles, causing two browser repaints.
As this is most likely a browser issue, and not something we can change, deferring the setting of the second style is the only way to make this work, and using a delay will still work even if it's set to just 1 milliseconds, or one could defer the execution with a regular timeout, which is the usual way to defer execution of a script:
$('div').css({ transition: '0s', width: 200 }); setTimeout(function() { $('div').css({ transition: '3s', width: 10 }); });
FIDDLE
The above will work just fine, as the timeout causes the first setting of the style to be painted by the browser, and defers the setting of the style inside the timeout to a later time, but as no time is set, it's executed as soon as the browser can (but still deferred until after the current script has completed), which for the human eye would seem like immediately, and that solves the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With