Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>Short Answer</h2> <p><strong>Use this CSS:</strong></p> <pre><code>.notransition { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important; } </code></pre> <p><strong>Plus either this JS (with jQuery)...</strong></p> <pre><code>$someElement.addClass('notransition'); // Disable transitions doWhateverCssChangesYouWant($someElement); $someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes $someElement.removeClass('notransition'); // Re-enable transitions </code></pre> <p>... or equivalent JavaScript using raw DOM functions or whatever other framework you're working with.</p> <h2>Explanation</h2> <p>This is actually a fairly subtle problem.</p> <p>First up, you probably want to create a 'notransition' class that you can apply to elements to set their <code>*-transition</code> CSS attributes to <code>none</code>. For instance:</p> <pre><code>.notransition { -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important; } </code></pre> <p><sub><i>(Minor aside - note the lack of an <code>-ms-transition</code> in there. You don't need it. The first version of Internet Explorer to support transitions <em>at all</em> was IE 10, which supported them unprefixed.)</i></sub></p> <p>But that's just style, and is the easy bit. When you come to try and use this class, you'll run into a trap. The trap is that code like this won't work the way you might naively expect:</p> <pre><code>// Don't do things this way! It doesn't work! $someElement.addClass('notransition') $someElement.css('height', '50px') // just an example; could be any CSS change $someElement.removeClass('notransition') </code></pre> <p>Naively, you might think that the change in height won't be animated, because it happens while the 'notransition' class is applied. In reality, though, it <em>will</em> be animated, at least in all modern browsers I've tried. The problem is that the browser is caching the styling changes that it needs to make until the JavaScript has finished executing, and then making all the changes in a single reflow. As a result, it does a reflow where there is no net change to whether or not transitions are enabled, but there is a net change to the height. Consequently, it animates the height change.</p> <p>You might think a reasonable and clean way to get around this would be to wrap the removal of the 'notransition' class in a 1ms timeout, like this:</p> <pre><code>// Don't do things this way! It STILL doesn't work! $someElement.addClass('notransition') $someElement.css('height', '50px') // just an example; could be any CSS change setTimeout(function () {$someElement.removeClass('notransition')}, 1); </code></pre> <p>but this doesn't reliably work either. I wasn't able to make the above code break in WebKit browsers, but on Firefox (on both slow and fast machines) you'll sometimes (seemingly at random) get the same behaviour as using the naive approach. I guess the reason for this is that it's possible for the JavaScript execution to be slow enough that the timeout function is waiting to execute by the time the browser is idle and would otherwise be thinking about doing an opportunistic reflow, and if that scenario happens, Firefox executes the queued function before the reflow.</p> <p>The only solution I've found to the problem is to <em>force</em> a reflow of the element, flushing the CSS changes made to it, before removing the 'notransition' class. There are various ways to do this - see <a href="http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html" rel="noreferrer">here</a> for some. The closest thing there is to a 'standard' way of doing this is to read the <code>offsetHeight</code> property of the element.</p> <p>One solution that actually works, then, is</p> <pre><code>$someElement.addClass('notransition'); // Disable transitions doWhateverCssChangesYouWant($someElement); $someElement[0].offsetHeight; // Trigger a reflow, flushing the CSS changes $someElement.removeClass('notransition'); // Re-enable transitions </code></pre> <p>Here's a JS fiddle that illustrates the three possible approaches I've described here (both the one successful approach and the two unsuccessful ones): <a href="http://jsfiddle.net/2uVAA/35/" rel="noreferrer">http://jsfiddle.net/2uVAA/35/</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload