Changing css with jQuery 2.1+ ignores transition property
Asked Answered
P

2

9

I am switching from jQuery 2.0.3 to 2.1.0.

I noticed that in v2.1.0 the css transition property is ignored when setting css properties directly

$('#someElement').css('width','100px');

In v2.0.3 , my element will maintain it's css transition, whereas I lose that in v2.1.0.

I am wondering why this is treated differently, and how I can 'turn on' the transition effect.

With jQuery 2.0.3, the css transition property takes effect

$(function() {
  $('.myClass').css('width', '100px');
});
.myClass {
  height: 50px;
  width: 300px;
  background-color: red;
  transition: width 3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<div class="myClass"></div>

With jQuery 2.1.0, the css transition property is ignored

$(function() {
  $('.myClass').css('width', '100px');
});
.myClass {
  height: 50px;
  width: 300px;
  background-color: red;
  transition: width 3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="myClass"></div>

Edit:

I am seeing this odd behavior in Chrome Version 47.0.2526.106 m

In Firefox 42.0, both animate properly

Phelloderm answered 18/12, 2015 at 3:29 Comment(9)
I don't see any differences! May be you have problem with your browser.Iguanodon
@OkiErieRinaldi What browser are you in? I can reproduce the OP's issue in the latest version of Chrome.Alkalosis
yes, I'm in Chrome Version 47.0.2526.106 . I'll add that to the questionPhelloderm
I'm in the latest version of firefox @JoshCrozier. The transitions go well.Iguanodon
if I use chrome, I usually add another property to the class. Try to add -webkit-transition: width 3s to the class property.Iguanodon
Weird, I am trying your code on fiddle and everything works fine for both chrome or firefox. But I am not sure why it doesn't work for chrome on SO code snippet. jsfiddle.net/z0qLahuuSubtenant
@OkiErieRinaldi didn't seem to do the trickPhelloderm
@Subtenant it seems ondomready vs onload was causing the discrepency. 2.1.0 only worked with onload, whereas 2.0.3 worked with bothPhelloderm
@EricPhillips It's probably similar issue to #32162053 and code.google.com/p/chromium/issues/detail?id=451756Subtenant
A
3

After searching around, I think this may be related to the changes made for issue #14164 during the v2.1.0 release. As per the title, "Reduce forced layout reflows in init or methods".

I compared the v2.0.3 source code with the v2.1.0 source code, and it looks like some refactoring was done around the .ready() method and how the events are deferred. More specifically, I think it may be related to line(s) 3407-3408 in v2.1.0 where the .ready() method is initially invoked (this wasn't present in v2.0.3):

// Kick off the DOM ready check even if the user does not
jQuery.ready.promise();

As for a workaround, it seems like this transition behavior is inconsistent across browsers. To resolve the issue in Chrome, you could defer the execution of the code and force a redraw.

setTimeout(function () {
  $('.myClass').css('width', '100px');
}, 0);
.myClass {
  height: 50px;
  width: 300px;
  background-color: red;
  transition: width 3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="myClass"></div>

Alternatively, you could also load jQuery after the DOM elements by moving the script to the bottom of your page. It's still baffling why this makes a difference in Chrome, but doesn't matter in Firefox; it must be related to how the DOM is drawn/painted after events.

$('.myClass').css('width', '100px');
.myClass {
  height: 50px;
  width: 300px;
  background-color: red;
  transition: width 3s;
}
<div class="myClass"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
Alkalosis answered 18/12, 2015 at 3:48 Comment(4)
You're right, it seems 2.1.0 in Chrome doesn't work with ondomready , only with onload, whereas 2.0.3 works with both jsfiddle.net/z0qLahuu Strange behaviorPhelloderm
It looks like it also works if you apply the css inside onclick function like $('.myClass').on('click', function(){ $('.myClass').css('width', '100px'); });Subtenant
@EricPhillips You're right. I searched around, and it was probably related to the reflow changes made for issue #14164. I updated the answer.Alkalosis
@JoshCrozier Thank you for the incredibly thorough/researched answer, much appreciated!Phelloderm
N
1

it also seems to work using animate() instead of css()

$('.myClass').animate({'width': '100px'});
.myClass {
  height: 50px;
  width: 300px;
  background-color: red;
  transition: width 3s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="myClass"></div>
Nogging answered 18/12, 2015 at 4:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.