New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

different result of width() and height() since jQuery 3.0 #3193

Closed
HolgerJeromin opened this Issue Jun 22, 2016 · 55 comments

Comments

Projects
None yet
@HolgerJeromin

HolgerJeromin commented Jun 22, 2016

Just to provide feedback:
#2439 has not only the impact returning non-integer values.

I have a CSS transform:scale(2) in a root element with a div which has css width 200px.
jQuery 2.x returns 200 for .width() as it uses offsetWidth
jQuery 3.0 returns 400 for .width() as it uses getBoundingClientRect()

This is a breaking change which should be at least mentioned in the upgrade guide.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jun 22, 2016

Member

Agreed! It's a good breaking change though, wouldn't you say?

As far as documenting, perhaps we could add a sentence to the existing item here? Either that or create an entirely new "Breaking change" item for it. Rewording the heading will break existing links.

https://jquery.com/upgrade-guide/3.0/#breaking-change-width-height-css-quot-width-quot-and-css-quot-height-quot-can-return-non-integer-values

Member

dmethvin commented Jun 22, 2016

Agreed! It's a good breaking change though, wouldn't you say?

As far as documenting, perhaps we could add a sentence to the existing item here? Either that or create an entirely new "Breaking change" item for it. Rewording the heading will break existing links.

https://jquery.com/upgrade-guide/3.0/#breaking-change-width-height-css-quot-width-quot-and-css-quot-height-quot-can-return-non-integer-values

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jun 22, 2016

.width() is now more correct, yes.
But it was kind of buggy since the beginning of jQuery.
So providing .displayWidth() instead of changing the meaning would be less painful for my application.
IMO this issue is worth a new entry in the upgrade guide.

HolgerJeromin commented Jun 22, 2016

.width() is now more correct, yes.
But it was kind of buggy since the beginning of jQuery.
So providing .displayWidth() instead of changing the meaning would be less painful for my application.
IMO this issue is worth a new entry in the upgrade guide.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jun 22, 2016

The current implementation has one problem. Setting and Getting via css() is not symmetric anymore:

$("#Button").css("width", 200)
$("#Button").css("width")
"400px"

HolgerJeromin commented Jun 22, 2016

The current implementation has one problem. Setting and Getting via css() is not symmetric anymore:

$("#Button").css("width", 200)
$("#Button").css("width")
"400px"
@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jun 22, 2016

Member

Good point, and that doesn't seem good. Not sure how to deal with it though. It would help if .css("width") returned the CSS value and .width() could return the actual width, but that would be another breaking change no doubt and perhaps worse than leaving it inconsistent.

Member

dmethvin commented Jun 22, 2016

Good point, and that doesn't seem good. Not sure how to deal with it though. It would help if .css("width") returned the CSS value and .width() could return the actual width, but that would be another breaking change no doubt and perhaps worse than leaving it inconsistent.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jun 22, 2016

Applications like mine have the defect right now.
Only a few people having an issue with transform.
If you change css() back half of these people are getting back a working solution (without changing own code) . The other half at least are able to adapt (without asking outerwidth themselves).
css() returning not the css but a computed value (possibly manipulated by a parent) is very surprising.

HolgerJeromin commented Jun 22, 2016

Applications like mine have the defect right now.
Only a few people having an issue with transform.
If you change css() back half of these people are getting back a working solution (without changing own code) . The other half at least are able to adapt (without asking outerwidth themselves).
css() returning not the css but a computed value (possibly manipulated by a parent) is very surprising.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jun 23, 2016

Member

jQuery's .css() tries really hard to return the computed value because that's usually the value people want. Browsers often don't provide a good way to get other values anyway so that's what we're stuck with. It's worth discussing with the team though to see what might be done here.

Member

dmethvin commented Jun 23, 2016

jQuery's .css() tries really hard to return the computed value because that's usually the value people want. Browsers often don't provide a good way to get other values anyway so that's what we're stuck with. It's worth discussing with the team though to see what might be done here.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jun 29, 2016

The change is still not in the upgrade guide. IMO this should be done as fast as possible to prevent upgraders to have the same problems as we had.

HolgerJeromin commented Jun 29, 2016

The change is still not in the upgrade guide. IMO this should be done as fast as possible to prevent upgraders to have the same problems as we had.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jun 29, 2016

Member

The reason no change has been made is because we haven't yet decided whether we should change code or docs. Once we do this ticket will be closed.

Member

dmethvin commented Jun 29, 2016

The reason no change has been made is because we haven't yet decided whether we should change code or docs. Once we do this ticket will be closed.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jun 30, 2016

Thanks for the explanation.
But IMO new Code should at least be version 3.0.1, so a warning against version 3.0 is useful in any case.

HolgerJeromin commented Jun 30, 2016

Thanks for the explanation.
But IMO new Code should at least be version 3.0.1, so a warning against version 3.0 is useful in any case.

@timmywil timmywil added the Dimensions label Jun 30, 2016

@Getfree

This comment has been minimized.

Show comment
Hide comment
@Getfree

Getfree Jul 8, 2016

If I may add my opinion....
The dimensions of an element and the bounding box of an element are two different concepts. I think we can agree on that.

What you are doing with this change is mixing this two concepts, so now there is no way of consistently getting the dimensions of an element. Rather, we get the dimensions or the bounding box depending on whether there are CSS transformations applied or not.

It's an acceptable breaking change if .width() and .height() now return the bounding box rather than the dimensions as long as we have a way of getting the true dimensions. Do we have such a way?

Also, .css() is supposed to give the computed css properties (hence its name), but if now .css('width') and .css('height') give the bounding box instead, that's not just a breaking change, that's messing with the user base. It's just a huge gotcha.

Getfree commented Jul 8, 2016

If I may add my opinion....
The dimensions of an element and the bounding box of an element are two different concepts. I think we can agree on that.

What you are doing with this change is mixing this two concepts, so now there is no way of consistently getting the dimensions of an element. Rather, we get the dimensions or the bounding box depending on whether there are CSS transformations applied or not.

It's an acceptable breaking change if .width() and .height() now return the bounding box rather than the dimensions as long as we have a way of getting the true dimensions. Do we have such a way?

Also, .css() is supposed to give the computed css properties (hence its name), but if now .css('width') and .css('height') give the bounding box instead, that's not just a breaking change, that's messing with the user base. It's just a huge gotcha.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jul 8, 2016

Just to add another point regarding relationship of .width() and .css('width'):

Note that .width() will always return the content width, regardless of the value of the CSS box-sizing property. [...] To avoid this penalty, use .css( "width" ) rather than .width().

This is documented behavior, have not checked if this is still valid for jQuery 3.0.

HolgerJeromin commented Jul 8, 2016

Just to add another point regarding relationship of .width() and .css('width'):

Note that .width() will always return the content width, regardless of the value of the CSS box-sizing property. [...] To avoid this penalty, use .css( "width" ) rather than .width().

This is documented behavior, have not checked if this is still valid for jQuery 3.0.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jul 8, 2016

Member

I think those are all valid points. As far as resolving the problem, there are conflicting concerns here, I'll just mention width but it applies to height as well.

  • Our previous use of offsetWidth was flaky because that property is not part of the documented standard and does not return fractional pixels. With subpixel rendering becoming common we were finding more cases where it got things wrong. That's why we switched to gBCR.
  • Historically, jQuery users have seen .width() as just a shorthand for .css("width"), although there are definitely cases both in past versions and 3.0 where that is not true. Ideally we'd like to find a solution that breaks the least code possible.
  • Since we're changing the results of existing APIs, it would be great if we could find a way for Migrate to identify and/or fix.

@HolgerJeromin @Getfree What would you like these APIs to return? Let's start with that and think about how existing code might break.

Member

dmethvin commented Jul 8, 2016

I think those are all valid points. As far as resolving the problem, there are conflicting concerns here, I'll just mention width but it applies to height as well.

  • Our previous use of offsetWidth was flaky because that property is not part of the documented standard and does not return fractional pixels. With subpixel rendering becoming common we were finding more cases where it got things wrong. That's why we switched to gBCR.
  • Historically, jQuery users have seen .width() as just a shorthand for .css("width"), although there are definitely cases both in past versions and 3.0 where that is not true. Ideally we'd like to find a solution that breaks the least code possible.
  • Since we're changing the results of existing APIs, it would be great if we could find a way for Migrate to identify and/or fix.

@HolgerJeromin @Getfree What would you like these APIs to return? Let's start with that and think about how existing code might break.

@Getfree

This comment has been minimized.

Show comment
Hide comment
@Getfree

Getfree Jul 8, 2016

The way I see it, it's essential that we have a reliable way of getting the dimensions and position of an element no matter if the element itself or an ancestor is css-transformed.

Consider this example:
jQuery 2.2: https://jsfiddle.net/dxueLvfk/
jQuery 3.1: https://jsfiddle.net/dxueLvfk/1/

The blue box wants to be exactly under the red box. But since the BODY element is transformed, bounding-box coordinates are no good.

In general, from the moment you apply css-transformations, any calculation based on elements dimensions is going to give the wrong result.
Even seemingly harmless transformations like 2D-translates cause problems on jQuery 2.0 already. (.offset() and .position() give bounding-box coordinates IIRC)

I'm Ok with jQuery 3 introducing breaking changes as long as there is a way of getting true element's dimensions (and not bounding-box dimensions) when they are needed.
But given that this won't be needed very often, there could be an alternate way of getting these, so that .width(), .height() and .position() can provide fractional pixels (at the expense of being useless when transformations are applied).

Getfree commented Jul 8, 2016

The way I see it, it's essential that we have a reliable way of getting the dimensions and position of an element no matter if the element itself or an ancestor is css-transformed.

Consider this example:
jQuery 2.2: https://jsfiddle.net/dxueLvfk/
jQuery 3.1: https://jsfiddle.net/dxueLvfk/1/

The blue box wants to be exactly under the red box. But since the BODY element is transformed, bounding-box coordinates are no good.

In general, from the moment you apply css-transformations, any calculation based on elements dimensions is going to give the wrong result.
Even seemingly harmless transformations like 2D-translates cause problems on jQuery 2.0 already. (.offset() and .position() give bounding-box coordinates IIRC)

I'm Ok with jQuery 3 introducing breaking changes as long as there is a way of getting true element's dimensions (and not bounding-box dimensions) when they are needed.
But given that this won't be needed very often, there could be an alternate way of getting these, so that .width(), .height() and .position() can provide fractional pixels (at the expense of being useless when transformations are applied).

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Jul 11, 2016

I'm Ok with jQuery 3 introducing breaking changes as long as there is a way of getting true element's dimensions (and not bounding-box dimensions) when they are needed.

Exactly. My application needs a way to get dimension based information for correct positioning of complex transformed elements.
Minimal example:
https://jsfiddle.net/3u4tug8t/2/

Non fractional value is no disadvantage if result is not complete bogus after transforming.

HolgerJeromin commented Jul 11, 2016

I'm Ok with jQuery 3 introducing breaking changes as long as there is a way of getting true element's dimensions (and not bounding-box dimensions) when they are needed.

Exactly. My application needs a way to get dimension based information for correct positioning of complex transformed elements.
Minimal example:
https://jsfiddle.net/3u4tug8t/2/

Non fractional value is no disadvantage if result is not complete bogus after transforming.

@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Jul 11, 2016

Member

Hmm, maybe we need to use offsetWidth and offsetHeight.

Are there any cases where you'd want the dimensions with transforms applied?

Member

timmywil commented Jul 11, 2016

Hmm, maybe we need to use offsetWidth and offsetHeight.

Are there any cases where you'd want the dimensions with transforms applied?

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Jul 11, 2016

Member

Let's start with a summary of documented surface area (using the horizontal dimension without loss of generality):

  • .css("width") returns the computed CSS "width" property, which will include or exclude padding and borders per the CSS "box-sizing" property.
  • .width() returns the computed content width, which may be less than .css("width") when "box-sizing" is "border-box" but should equal it when "box-sizing" is "content-box".
  • .innerWidth() returns the computed padding box width (sum of .width() and computed left and right padding).
  • .outerWidth() returns the computed border box width (sum of .innerWidth() and computed left and right borders), which should equal .css("width") when "box-sizing" is "border-box".
  • .outerWidth(true) returns the computed margin box width (sum of .outerWidth() and computed left and right margins).

All of these should be capable of returning fractional values, but—since they are so closely tied to the CSS box model and especially since they're all also setters—ignore transforms. In fact, the non-css methods are probably the most convenient means of getting untransformed dimensions, although if we were starting from scratch we might want to condense them together and would definitely be more consistent with naming.

For this ticket, though, I have to agree with @HolgerJeromin. We should not use getBoundingClientRect values in any of the above calls.

Member

gibson042 commented Jul 11, 2016

Let's start with a summary of documented surface area (using the horizontal dimension without loss of generality):

  • .css("width") returns the computed CSS "width" property, which will include or exclude padding and borders per the CSS "box-sizing" property.
  • .width() returns the computed content width, which may be less than .css("width") when "box-sizing" is "border-box" but should equal it when "box-sizing" is "content-box".
  • .innerWidth() returns the computed padding box width (sum of .width() and computed left and right padding).
  • .outerWidth() returns the computed border box width (sum of .innerWidth() and computed left and right borders), which should equal .css("width") when "box-sizing" is "border-box".
  • .outerWidth(true) returns the computed margin box width (sum of .outerWidth() and computed left and right margins).

All of these should be capable of returning fractional values, but—since they are so closely tied to the CSS box model and especially since they're all also setters—ignore transforms. In fact, the non-css methods are probably the most convenient means of getting untransformed dimensions, although if we were starting from scratch we might want to condense them together and would definitely be more consistent with naming.

For this ticket, though, I have to agree with @HolgerJeromin. We should not use getBoundingClientRect values in any of the above calls.

@gibson042 gibson042 added this to the 3.1.1 milestone Jul 11, 2016

@gibson042 gibson042 removed the Needs review label Jul 11, 2016

@Getfree

This comment has been minimized.

Show comment
Hide comment
@Getfree

Getfree Jul 13, 2016

Also remember that .position() and .offset() make use of getBoundingClientRect as well, which means they give wrong results when transformations are applied.

Example: https://jsfiddle.net/au6uem3p/

Getfree commented Jul 13, 2016

Also remember that .position() and .offset() make use of getBoundingClientRect as well, which means they give wrong results when transformations are applied.

Example: https://jsfiddle.net/au6uem3p/

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member

@Getfree I wouldn't say they give "wrong" results as they do return the element displayed position.

Going back to basics, I was wondering what are the main questions being asked that jQuery (or a browser API for that matter) should answer to. I see 3 of them related to width handling:

  1. "What is the computed/resolved value of width?". The $(node).css('width') and getComputedStyle(node).width APIs are supposed to answer that question. They shouldn't take transforms into account as transforms are only influencing the final dimensions of the element on the screen, not the width computed value. I agree our current behavior is buggy here.
  2. "How can I set the new width value of the element?". The $(node).css('width', value) and node.style.width = value APIs answer to that question. It makes sense that on the jQuery side the .css() method serves both as a getter and setter as those APIs respond to each other - if you set a particular width, you'll generally get the same one from the getter. This is BTW why I agree our current behavior of the .css('width') getter that takes transforms into account is buggy.
  3. "What are the element's displayed dimensions on the screen?". This question is about how the element is displayed on the screen so it should include transforms. On the other hand, since it's not about a single property but it takes all of the things into account this API shouldn't have a setter equivalent as it's not clear what exactly it would be setting. On the jQuery side this has been the responsibility of the .width() API, although the .css('width') getter now more or less behaves in the same way (if you ignore box-sizing).

The browser APIs have been evolving in a way that should satisfy the above conditions. There is no API to get the displayed size of the element but without taking transitions into account; asking for something like that is kind of weird, most of the time people asking this question are really asking for the value of the computed width, not the displayed width minus transforms. AFAIK there is no browser API that would answer this question as well. There is innerWidth but it's treated as obsolete and Web compatibility is the only reason why it doesn't take transforms into account as well as returns decimal values only (I hope I got this paragraph right, I'd love someone working on a browser to confirm/deny it, though. @bzbarsky?)

Now, as for the last point - our problem is that the .width() method would be fine on its own as a getter of the final displayed size of the element but it also serves as a setter for us which undermines this purpose. It doesn't make it easier that we also have the .innerWidth() and .outerWidth() methods that serve both as getters and setters. The fact that all those APIs are setters as well is actually terrible - they need to know the value of box-sizing so the style write triggers the style read which means those APIs have layout thrashing built-in. I think it's bad we have APIs like that.

If we want to leave .innerWidth(), .outerWidth() and .width() as both getters and setters as they're now it seems they should be converted to fulfill the first two use cases as @gibson042 suggested. But then we don't have any jQuery API to return the dimensions of the element on the screen while we do have the API returning the position of the element on the screen. Should we have a new API for the former?

Member

mgol commented Jul 13, 2016

@Getfree I wouldn't say they give "wrong" results as they do return the element displayed position.

Going back to basics, I was wondering what are the main questions being asked that jQuery (or a browser API for that matter) should answer to. I see 3 of them related to width handling:

  1. "What is the computed/resolved value of width?". The $(node).css('width') and getComputedStyle(node).width APIs are supposed to answer that question. They shouldn't take transforms into account as transforms are only influencing the final dimensions of the element on the screen, not the width computed value. I agree our current behavior is buggy here.
  2. "How can I set the new width value of the element?". The $(node).css('width', value) and node.style.width = value APIs answer to that question. It makes sense that on the jQuery side the .css() method serves both as a getter and setter as those APIs respond to each other - if you set a particular width, you'll generally get the same one from the getter. This is BTW why I agree our current behavior of the .css('width') getter that takes transforms into account is buggy.
  3. "What are the element's displayed dimensions on the screen?". This question is about how the element is displayed on the screen so it should include transforms. On the other hand, since it's not about a single property but it takes all of the things into account this API shouldn't have a setter equivalent as it's not clear what exactly it would be setting. On the jQuery side this has been the responsibility of the .width() API, although the .css('width') getter now more or less behaves in the same way (if you ignore box-sizing).

The browser APIs have been evolving in a way that should satisfy the above conditions. There is no API to get the displayed size of the element but without taking transitions into account; asking for something like that is kind of weird, most of the time people asking this question are really asking for the value of the computed width, not the displayed width minus transforms. AFAIK there is no browser API that would answer this question as well. There is innerWidth but it's treated as obsolete and Web compatibility is the only reason why it doesn't take transforms into account as well as returns decimal values only (I hope I got this paragraph right, I'd love someone working on a browser to confirm/deny it, though. @bzbarsky?)

Now, as for the last point - our problem is that the .width() method would be fine on its own as a getter of the final displayed size of the element but it also serves as a setter for us which undermines this purpose. It doesn't make it easier that we also have the .innerWidth() and .outerWidth() methods that serve both as getters and setters. The fact that all those APIs are setters as well is actually terrible - they need to know the value of box-sizing so the style write triggers the style read which means those APIs have layout thrashing built-in. I think it's bad we have APIs like that.

If we want to leave .innerWidth(), .outerWidth() and .width() as both getters and setters as they're now it seems they should be converted to fulfill the first two use cases as @gibson042 suggested. But then we don't have any jQuery API to return the dimensions of the element on the screen while we do have the API returning the position of the element on the screen. Should we have a new API for the former?

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member

I've tried removing the width & height hooks for .css() (saving 366 bytes gzipped in the process) and I got 94 test failures but most in the dimensions module. In the css module the only failing tests were the ones checking .css('width') on a disconnected node or with negative values. This means, though, that switching to getComputedStyle for width & height is not doable before 4.0. I also think we can't switch back to offsetWidth before 4.0 as that would break the jQuery 3.0 contract that we don't cut off fractional values. Besides, I'd really like to avoid going back to fractional values.

I'm not sure if there's anything we can do before 4.0.

Member

mgol commented Jul 13, 2016

I've tried removing the width & height hooks for .css() (saving 366 bytes gzipped in the process) and I got 94 test failures but most in the dimensions module. In the css module the only failing tests were the ones checking .css('width') on a disconnected node or with negative values. This means, though, that switching to getComputedStyle for width & height is not doable before 4.0. I also think we can't switch back to offsetWidth before 4.0 as that would break the jQuery 3.0 contract that we don't cut off fractional values. Besides, I'd really like to avoid going back to fractional values.

I'm not sure if there's anything we can do before 4.0.

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member

Going back to position and offset for a moment - we're using getBoundingClientRect() to retrieve them and this API does take transforms into account (on purpose). John Resig wrote a while ago about why this API is awesome and how it saves both code complexity & size as well as gives a speed boost. I don't see us going back to the previous implementation, it would hurt too much on those fronts and I still think that many people will want the current behavior so going back to the previous one would hurt them as well. The problem is that .offset() serves as a setter as well... Which makes for a non-symmetrical API. I don't really know what to do about it.

Member

mgol commented Jul 13, 2016

Going back to position and offset for a moment - we're using getBoundingClientRect() to retrieve them and this API does take transforms into account (on purpose). John Resig wrote a while ago about why this API is awesome and how it saves both code complexity & size as well as gives a speed boost. I don't see us going back to the previous implementation, it would hurt too much on those fronts and I still think that many people will want the current behavior so going back to the previous one would hurt them as well. The problem is that .offset() serves as a setter as well... Which makes for a non-symmetrical API. I don't really know what to do about it.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jul 13, 2016

Member

Seems like @mgol has explained the challenges here pretty well. Any API that retrieves the actual transformed dimension or position as a single number is taking several CSS properties into account and can't be used as both a getter and setter to round-trip that single number.

What can we do before 4.0? I'd consider some of this to be regressions so even if it changes existing behavior for better compatibility with 2.x it still may be in play for a 3.x.0 release.

Member

dmethvin commented Jul 13, 2016

Seems like @mgol has explained the challenges here pretty well. Any API that retrieves the actual transformed dimension or position as a single number is taking several CSS properties into account and can't be used as both a getter and setter to round-trip that single number.

What can we do before 4.0? I'd consider some of this to be regressions so even if it changes existing behavior for better compatibility with 2.x it still may be in play for a 3.x.0 release.

@bzbarsky

This comment has been minimized.

Show comment
Hide comment
@bzbarsky

bzbarsky Jul 13, 2016

I'd love someone working on a browser to confirm/deny it

Browsers have getComputedStyle().width for returning the "used width" in CSS terms for everything except non-replaced inlines: the layout width, ignoring transforms. I think this is what you're calling "the displayed size of the element but without taking transitions into account". So an API for this already exists, again for everything except non-replaced inlines (think <span>).

There is no browser API for returning the "computed width" in CSS terms. Put another way, if you have: <div style="width: 100px"><div></div></div> and do getComputedStyle().width on the inner div, browsers will return "100px", whereas the CSS computed width there is "auto".

innerWidth is a thing on Window, so not relevant here. There's things like offsetWidth which do return non-transformed values, and might do something sane on non-replaced inlines, but as you note are integer-only.

bzbarsky commented Jul 13, 2016

I'd love someone working on a browser to confirm/deny it

Browsers have getComputedStyle().width for returning the "used width" in CSS terms for everything except non-replaced inlines: the layout width, ignoring transforms. I think this is what you're calling "the displayed size of the element but without taking transitions into account". So an API for this already exists, again for everything except non-replaced inlines (think <span>).

There is no browser API for returning the "computed width" in CSS terms. Put another way, if you have: <div style="width: 100px"><div></div></div> and do getComputedStyle().width on the inner div, browsers will return "100px", whereas the CSS computed width there is "auto".

innerWidth is a thing on Window, so not relevant here. There's things like offsetWidth which do return non-transformed values, and might do something sane on non-replaced inlines, but as you note are integer-only.

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member

Browsers have getComputedStyle().width for returning the "used width" in CSS terms for everything except non-replaced inlines: the layout width, ignoring transforms. I think this is what you're calling "the displayed size of the element but without taking transitions into account". So an API for this already exists, again for everything except non-replaced inlines (think ).

I actually meant the bounding box of the element i.e. "what's the size of the box that appears on the screen", so including transforms.

There is no browser API for returning the "computed width" in CSS terms. Put another way, if you have:

and do getComputedStyle().width on the inner div, browsers will return "100px", whereas the CSS computed width there is "auto".

I meant "resolved width"; I keep using the wrong name because of how getComputedStyle is named.

innerWidth is a thing on Window, so not relevant here. There's things like offsetWidth which do return non-transformed values, and might do something sane on non-replaced inlines, but as you note are integer-only.

I meant "offsetWidth" here, I keep mixing stuff, d'oh. Post corrected.

Basically, my point was that you may either ask for a resolved value for a specific CSS property, here: width or you can ask for the dimensions of the final box as it appears on the screen (i.e. the bounding box of the element). There is no API to get the bounding box minus transforms and while for width the getComputedStyle(node).width may be a good approximation, there is no similar API that we could use for offset() - you either get transforms included (via node.getBoundingClientRect().left) or you must compute the whole thing by yourself, traversing the document which is expensive.

Member

mgol commented Jul 13, 2016

Browsers have getComputedStyle().width for returning the "used width" in CSS terms for everything except non-replaced inlines: the layout width, ignoring transforms. I think this is what you're calling "the displayed size of the element but without taking transitions into account". So an API for this already exists, again for everything except non-replaced inlines (think ).

I actually meant the bounding box of the element i.e. "what's the size of the box that appears on the screen", so including transforms.

There is no browser API for returning the "computed width" in CSS terms. Put another way, if you have:

and do getComputedStyle().width on the inner div, browsers will return "100px", whereas the CSS computed width there is "auto".

I meant "resolved width"; I keep using the wrong name because of how getComputedStyle is named.

innerWidth is a thing on Window, so not relevant here. There's things like offsetWidth which do return non-transformed values, and might do something sane on non-replaced inlines, but as you note are integer-only.

I meant "offsetWidth" here, I keep mixing stuff, d'oh. Post corrected.

Basically, my point was that you may either ask for a resolved value for a specific CSS property, here: width or you can ask for the dimensions of the final box as it appears on the screen (i.e. the bounding box of the element). There is no API to get the bounding box minus transforms and while for width the getComputedStyle(node).width may be a good approximation, there is no similar API that we could use for offset() - you either get transforms included (via node.getBoundingClientRect().left) or you must compute the whole thing by yourself, traversing the document which is expensive.

@bzbarsky

This comment has been minimized.

Show comment
Hide comment
@bzbarsky

bzbarsky Jul 13, 2016

Yes, that's a correct summary of the state of browser API.

bzbarsky commented Jul 13, 2016

Yes, that's a correct summary of the state of browser API.

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Jul 13, 2016

Member

What can we do before 4.0? I'd consider some of this to be regressions so even if it changes existing behavior for better compatibility with 2.x it still may be in play for a 3.x.0 release.

  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".
  • Rename and refactor the .width/.height/.inner*/.outer* surface area to clarify that they get/set CSS content/padding/border/margin box dimensions (and therefore ignore transforms). Reimplement the existing methods as thin wrappers.
  • Separately, address .offset and .position:
    • Complete and land gh-3096 or a derivative
    • Refactor to avoid dependence upon CSS width/height hooks, allowing the hooks to be removed
    • Document that .offset( setterArg ) is not reliable for elements with transformed ancestors
    • Document that .position() is not reliable for elements with transformed ancestors
Member

gibson042 commented Jul 13, 2016

What can we do before 4.0? I'd consider some of this to be regressions so even if it changes existing behavior for better compatibility with 2.x it still may be in play for a 3.x.0 release.

  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".
  • Rename and refactor the .width/.height/.inner*/.outer* surface area to clarify that they get/set CSS content/padding/border/margin box dimensions (and therefore ignore transforms). Reimplement the existing methods as thin wrappers.
  • Separately, address .offset and .position:
    • Complete and land gh-3096 or a derivative
    • Refactor to avoid dependence upon CSS width/height hooks, allowing the hooks to be removed
    • Document that .offset( setterArg ) is not reliable for elements with transformed ancestors
    • Document that .position() is not reliable for elements with transformed ancestors
@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Jul 13, 2016

Member

Considering the impact of some of these changes, moving to 3.2.0. We'll get smaller issues out in a 3.1.1 first.

Member

timmywil commented Jul 13, 2016

Considering the impact of some of these changes, moving to 3.2.0. We'll get smaller issues out in a 3.1.1 first.

@timmywil timmywil modified the milestones: 3.2.0, 3.1.1 Jul 13, 2016

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member
  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".

By reverting them to offsetWidth, I assume? I still consider it a small breaking change but maybe that's the best solution. I assume some people will depend on having access to fractional values and changing that back may break their sites so if we want to do this, we shouldn't wait too long IMO.

  • Rename and refactor the .width/.height/.inner*/.outer* surface area to clarify that they get/set CSS content/padding/border/margin box dimensions (and therefore ignore transforms). Reimplement the existing methods as thin wrappers.

I'll reiterate that I consider those setters to be bad APIs due to having layout thrashing built in. We've tried to drastically simplify .show()/.hide() for performance reasons (among other purposes but that's how it started) and we reverted the most problematic change because for many people there was no good replacement for force-showing cascade-hidden elements. In the case of the .width/.height/.inner*/.outer* APIs that's not the case. Could we ever remove those setters?

  • Separately, address .offset and .position:
    • Complete and land gh-3096 or a derivative
    • Refactor to avoid dependence upon CSS width/height hooks, allowing the hooks to be removed
    • Document that .offset( setterArg ) is not reliable for elements with transformed ancestors
    • Document that .position() is not reliable for elements with transformed ancestors

This sounds good to me.

Member

mgol commented Jul 13, 2016

  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".

By reverting them to offsetWidth, I assume? I still consider it a small breaking change but maybe that's the best solution. I assume some people will depend on having access to fractional values and changing that back may break their sites so if we want to do this, we shouldn't wait too long IMO.

  • Rename and refactor the .width/.height/.inner*/.outer* surface area to clarify that they get/set CSS content/padding/border/margin box dimensions (and therefore ignore transforms). Reimplement the existing methods as thin wrappers.

I'll reiterate that I consider those setters to be bad APIs due to having layout thrashing built in. We've tried to drastically simplify .show()/.hide() for performance reasons (among other purposes but that's how it started) and we reverted the most problematic change because for many people there was no good replacement for force-showing cascade-hidden elements. In the case of the .width/.height/.inner*/.outer* APIs that's not the case. Could we ever remove those setters?

  • Separately, address .offset and .position:
    • Complete and land gh-3096 or a derivative
    • Refactor to avoid dependence upon CSS width/height hooks, allowing the hooks to be removed
    • Document that .offset( setterArg ) is not reliable for elements with transformed ancestors
    • Document that .position() is not reliable for elements with transformed ancestors

This sounds good to me.

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Jul 13, 2016

Member
  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".

By reverting them to offsetWidth, I assume?

No, getComputedStyle is fine, just like is used for other .css calls.

I'll reiterate that I consider those setters to be bad APIs due to having layout thrashing built in. We've tried to drastically simplify .show()/.hide() for performance reasons (among other purposes but that's how it started) and we reverted the most problematic change because for many people there was no good replacement for force-showing cascade-hidden elements. In the case of the .width/.height/.inner*/.outer* APIs that's not the case. Could we ever remove those setters?

It's possible, but as I mentioned above, I believe these methods to be the most convenient means of interacting with the CSS box model—getting rid of the setter logic would leave a vacuum. And note that the layout thrashing only comes into play with property/box-sizing mismatches (e.g., $contentBox.width( val ) and $borderBox.outerWidth( val ) are equivalent to .css( "width", val )).

Member

gibson042 commented Jul 13, 2016

  • Remove getBoundingClientRect() from getWidthOrHeight so .css("width") once again accurately provides CSS "width".

By reverting them to offsetWidth, I assume?

No, getComputedStyle is fine, just like is used for other .css calls.

I'll reiterate that I consider those setters to be bad APIs due to having layout thrashing built in. We've tried to drastically simplify .show()/.hide() for performance reasons (among other purposes but that's how it started) and we reverted the most problematic change because for many people there was no good replacement for force-showing cascade-hidden elements. In the case of the .width/.height/.inner*/.outer* APIs that's not the case. Could we ever remove those setters?

It's possible, but as I mentioned above, I believe these methods to be the most convenient means of interacting with the CSS box model—getting rid of the setter logic would leave a vacuum. And note that the layout thrashing only comes into play with property/box-sizing mismatches (e.g., $contentBox.width( val ) and $borderBox.outerWidth( val ) are equivalent to .css( "width", val )).

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Jul 13, 2016

Member

I mentioned in one of my comments why I think switching to gCS would be a breaking change; we currently guarantee css('width') works even on detached elements.

Member

mgol commented Jul 13, 2016

I mentioned in one of my comments why I think switching to gCS would be a breaking change; we currently guarantee css('width') works even on detached elements.

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Jul 14, 2016

Member

a) we should probably deprecate that
b) but disconnected nodes already fall back to inline styles, and || "0px" isn't the worst of sins

Member

gibson042 commented Jul 14, 2016

a) we should probably deprecate that
b) but disconnected nodes already fall back to inline styles, and || "0px" isn't the worst of sins

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Jul 15, 2016

Member

Our heroic efforts to get the dimensions of detached or hidden elements were (in retrospect) a mistake IMO. Deprecating them ASAP seems like a good idea and warning in Migrate if we can, but I suspect it will be a while before we could remove it.

Member

dmethvin commented Jul 15, 2016

Our heroic efforts to get the dimensions of detached or hidden elements were (in retrospect) a mistake IMO. Deprecating them ASAP seems like a good idea and warning in Migrate if we can, but I suspect it will be a while before we could remove it.

@JoolsCaesar

This comment has been minimized.

Show comment
Hide comment
@JoolsCaesar

JoolsCaesar Jul 29, 2016

Are you aware that this breaks draggables in jquery UI 1.11.4?

this.helper.width( this.helper.width() );

So draggables grow/shrink whenever you move them. I have yet to test 1.12.

JoolsCaesar commented Jul 29, 2016

Are you aware that this breaks draggables in jquery UI 1.11.4?

this.helper.width( this.helper.width() );

So draggables grow/shrink whenever you move them. I have yet to test 1.12.

@Wykks

This comment has been minimized.

Show comment
Hide comment
@Wykks

Wykks Aug 9, 2016

It's breaking jquery-ui 1.12 draggable / resizable too

Wykks commented Aug 9, 2016

It's breaking jquery-ui 1.12 draggable / resizable too

@JoolsCaesar

This comment has been minimized.

Show comment
Hide comment
@JoolsCaesar

JoolsCaesar Aug 10, 2016

In what way? Upgrading to 1.12 fixed the problem I was facing, as the weird width=width line has been removed.

JoolsCaesar commented Aug 10, 2016

In what way? Upgrading to 1.12 fixed the problem I was facing, as the weird width=width line has been removed.

@HolgerJeromin

This comment has been minimized.

Show comment
Hide comment
@HolgerJeromin

HolgerJeromin Nov 8, 2016

BTW: Some Release Notes have a section known issues for such things.

Just wanted to add that the Syntax .css( "width", "+=200" ) is probably affected, too.

HolgerJeromin commented Nov 8, 2016

BTW: Some Release Notes have a section known issues for such things.

Just wanted to add that the Syntax .css( "width", "+=200" ) is probably affected, too.

@sabaca

This comment has been minimized.

Show comment
Hide comment
@sabaca

sabaca Nov 22, 2016

you can use something like that (for jquery-3.1.1-min.js):
/* for fix 1 */var _is_IE=window.navigator.userAgent.indexOf('MSIE ')>0; .... if( /* fix 1 */ _is_IE&& /* end fix 1 */ a.getClientRects().length&&(d=a.getBoundingClientRect()[b]), ...

sabaca commented Nov 22, 2016

you can use something like that (for jquery-3.1.1-min.js):
/* for fix 1 */var _is_IE=window.navigator.userAgent.indexOf('MSIE ')>0; .... if( /* fix 1 */ _is_IE&& /* end fix 1 */ a.getClientRects().length&&(d=a.getBoundingClientRect()[b]), ...

@craigkovatch

This comment has been minimized.

Show comment
Hide comment
@craigkovatch

craigkovatch Nov 29, 2016

@dmethvin that's a disappointing response. It places the onus on every developer to search through all open issues in jQuery rather than including it in e.g. a 'breaking changes/known issues' section of release notes.

craigkovatch commented Nov 29, 2016

@dmethvin that's a disappointing response. It places the onus on every developer to search through all open issues in jQuery rather than including it in e.g. a 'breaking changes/known issues' section of release notes.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Nov 29, 2016

Member

@craigkovatch I think we all had hoped it could be fixed more quickly. Perhaps we need to fall back to assuming this won't be fixed in 3.x and will have to wait for 4.x since it's a breaking change. Would you like to submit an addition to https://github.com/jquery/jquery.com/blob/master/pages/upgrade-guide/3.0.md to document this?

Member

dmethvin commented Nov 29, 2016

@craigkovatch I think we all had hoped it could be fixed more quickly. Perhaps we need to fall back to assuming this won't be fixed in 3.x and will have to wait for 4.x since it's a breaking change. Would you like to submit an addition to https://github.com/jquery/jquery.com/blob/master/pages/upgrade-guide/3.0.md to document this?

@craigkovatch

This comment has been minimized.

Show comment
Hide comment
@craigkovatch

craigkovatch Nov 29, 2016

@dmethvin I'm concerned that breaking in 3.x and restoring in 4.x is going to make the situation even worse. Really hoping this can still end up in a 3.x release. I'm happy to document in the upgrade-guide. Would this be a candidate for inclusion in the migration plugin?

craigkovatch commented Nov 29, 2016

@dmethvin I'm concerned that breaking in 3.x and restoring in 4.x is going to make the situation even worse. Really hoping this can still end up in a 3.x release. I'm happy to document in the upgrade-guide. Would this be a candidate for inclusion in the migration plugin?

@workmanw

This comment has been minimized.

Show comment
Hide comment
@workmanw

workmanw Dec 2, 2016

We were burned by this :(. Our app offers a whiteboarding-like tool that has drag/drop, element resize, and scaling. This change definitely caught us off guard. There is a lot of great discussion here. The only thing I'll add is that it's very unexpected that outerWidth would be the painted size instead of the layout size. When dealing with element dimensions in this way, it seems more desirable to have layout dimensions.

I definitely see how this is kind of quagmire because you don't want to make a breaking change for 3.x. Would you guys consider adding an argument to outerWidth or event another function to optionally restore this behavior?

workmanw commented Dec 2, 2016

We were burned by this :(. Our app offers a whiteboarding-like tool that has drag/drop, element resize, and scaling. This change definitely caught us off guard. There is a lot of great discussion here. The only thing I'll add is that it's very unexpected that outerWidth would be the painted size instead of the layout size. When dealing with element dimensions in this way, it seems more desirable to have layout dimensions.

I definitely see how this is kind of quagmire because you don't want to make a breaking change for 3.x. Would you guys consider adding an argument to outerWidth or event another function to optionally restore this behavior?

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Dec 2, 2016

Member

I think we know what the 3.x fix looks like, it's just a matter of someone volunteering the time to implement it (most of the core contributors, myself included, have been pulled in other directions in the latter half of this year).

Member

gibson042 commented Dec 2, 2016

I think we know what the 3.x fix looks like, it's just a matter of someone volunteering the time to implement it (most of the core contributors, myself included, have been pulled in other directions in the latter half of this year).

@vanderlee

This comment has been minimized.

Show comment
Hide comment
@vanderlee

vanderlee Dec 5, 2016

Contributor

I too have code breaking due to this undocumented backwards incompatibility.
What it the current best practice for working around this issue and getting the untransformed .outerWidth?

Contributor

vanderlee commented Dec 5, 2016

I too have code breaking due to this undocumented backwards incompatibility.
What it the current best practice for working around this issue and getting the untransformed .outerWidth?

@workmanw

This comment has been minimized.

Show comment
Hide comment
@workmanw

workmanw Dec 5, 2016

@vanderlee As a work around, I added the following utility functions to our application.

function _jQuerySize(elem, name) {
  if (typeof elem === 'string') {
    elem = jQuery(elem);
  }
  if (elem instanceof jQuery) {
    elem = elem[0];
  }

  let val = jQuery.style(elem, name);
  return parseFloat(val);
}

export function outerWidth(elem) {
  return _jQuerySize(elem, 'width');
}

export function outerHeight(elem) {
  return _jQuerySize(elem, 'height');
}

Then to use it:

import { outerWidth } from 'utils/jquery.js';

outerWidth('.user-item');
// or
let $userItem = $('.user-item');
outerWidth($userItem);

You could probably even monkey patch jQuery if you have 3rd party libraries that depend on this behavior ... but that felt a bit dangerous.

workmanw commented Dec 5, 2016

@vanderlee As a work around, I added the following utility functions to our application.

function _jQuerySize(elem, name) {
  if (typeof elem === 'string') {
    elem = jQuery(elem);
  }
  if (elem instanceof jQuery) {
    elem = elem[0];
  }

  let val = jQuery.style(elem, name);
  return parseFloat(val);
}

export function outerWidth(elem) {
  return _jQuerySize(elem, 'width');
}

export function outerHeight(elem) {
  return _jQuerySize(elem, 'height');
}

Then to use it:

import { outerWidth } from 'utils/jquery.js';

outerWidth('.user-item');
// or
let $userItem = $('.user-item');
outerWidth($userItem);

You could probably even monkey patch jQuery if you have 3rd party libraries that depend on this behavior ... but that felt a bit dangerous.

@roeycohen

This comment has been minimized.

Show comment
Hide comment
@roeycohen

roeycohen Feb 15, 2017

you may find alternative implementations of width of height functions in this site:
http://youmightnotneedjquery.com/
they seems to work the way it used to be before jquery 3.

roeycohen commented Feb 15, 2017

you may find alternative implementations of width of height functions in this site:
http://youmightnotneedjquery.com/
they seems to work the way it used to be before jquery 3.

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Mar 17, 2017

Member

The fix for this issue brought a regression: #3571. It seems we don't have a good Web API to satisfy our needs:

  1. getComputedStyle(elem).width always returns auto for inline elements.
  2. offsetWidth doesn't support fractional values.
  3. elem.getBoundingClientRect().width takes transforms into account.

Is there any way to retrieve a fractional "real" value for width on inline elements that doesn't take transforms into account? @bzbarsky?

Member

mgol commented Mar 17, 2017

The fix for this issue brought a regression: #3571. It seems we don't have a good Web API to satisfy our needs:

  1. getComputedStyle(elem).width always returns auto for inline elements.
  2. offsetWidth doesn't support fractional values.
  3. elem.getBoundingClientRect().width takes transforms into account.

Is there any way to retrieve a fractional "real" value for width on inline elements that doesn't take transforms into account? @bzbarsky?

@Krinkle

This comment has been minimized.

Show comment
Hide comment
@Krinkle

Krinkle Mar 17, 2017

Member

quote:
Consider this example:
jQuery 2.2: https://jsfiddle.net/dxueLvfk/
jQuery 3.1: https://jsfiddle.net/dxueLvfk/1/

Updated example to show that transforms can be just as well expected as unexpected. Then positioning something near another element, for example (using jQuery 3.1.1):
https://jsfiddle.net/dxueLvfk/6/
screen shot 2017-03-16 at 18 05 23

Here, the behaviour toward transform(), made it work as expected for the absolutely positioned element ("bare") that is in the DOM outside the transformed area. At the same time, the absolutely positioned element inside the transformed is not rendered as expected.

So in the end, there is no way to make it work for everything because crucial knowledge about the context is not given to the method. This is a lot like the difference between offset() and position().

Member

Krinkle commented Mar 17, 2017

quote:
Consider this example:
jQuery 2.2: https://jsfiddle.net/dxueLvfk/
jQuery 3.1: https://jsfiddle.net/dxueLvfk/1/

Updated example to show that transforms can be just as well expected as unexpected. Then positioning something near another element, for example (using jQuery 3.1.1):
https://jsfiddle.net/dxueLvfk/6/
screen shot 2017-03-16 at 18 05 23

Here, the behaviour toward transform(), made it work as expected for the absolutely positioned element ("bare") that is in the DOM outside the transformed area. At the same time, the absolutely positioned element inside the transformed is not rendered as expected.

So in the end, there is no way to make it work for everything because crucial knowledge about the context is not given to the method. This is a lot like the difference between offset() and position().

@mgol

This comment has been minimized.

Show comment
Hide comment
@mgol

mgol Mar 17, 2017

Member
Member

mgol commented Mar 17, 2017

@bzbarsky

This comment has been minimized.

Show comment
Hide comment
@bzbarsky

bzbarsky Mar 17, 2017

Is there any way to retrieve a fractional "real" value for width on inline elements that doesn't take transforms into account

Not that's shipping in browsers. In fact maybe even that's not shipping; I thought that that https://drafts.csswg.org/cssom-view/#dom-geometryutils-getboxquads using the node itself as the relativeTo value might do the trick, but you'd probably still get post-transform sizes.

(I should note that asking for the "width" of a non-replaced inline is a fairly odd question, especially as soon as there's a linebreak in the middle of it.)

bzbarsky commented Mar 17, 2017

Is there any way to retrieve a fractional "real" value for width on inline elements that doesn't take transforms into account

Not that's shipping in browsers. In fact maybe even that's not shipping; I thought that that https://drafts.csswg.org/cssom-view/#dom-geometryutils-getboxquads using the node itself as the relativeTo value might do the trick, but you'd probably still get post-transform sizes.

(I should note that asking for the "width" of a non-replaced inline is a fairly odd question, especially as soon as there's a linebreak in the middle of it.)

restonexyz added a commit to restonexyz/jquery that referenced this issue Feb 3, 2018

up (#1)
* Dimensions: ignore transforms when retrieving width/height

Close gh-3561
Fixes gh-3193

* CSS: remove dead code in getWidthOrHeight

- getCSS already falls back to inline styles

Ref gh-3561

* Release: update release dependencies

* Release: update AUTHORS.txt

* Release: update version to 3.2.0-pre

* Release: md5sum -> md5 -r for MAC

* Build: Updating the master version to 3.2.1-pre.

* Release: edit dist README version on release

Fixes gh-3574

* Build: update PR template

- Comment out things we don't need to see in the PR description
- Change CLA link

* Tests: move readywait to an iframe test

Close gh-3576
Fixes gh-3573

* Dimensions: fall back to offsetWidth/Height for inline elems

Close gh-3577
Fixes gh-3571

* Revert "Event: Trigger checkbox and radio click events identically"

This reverts commit b442aba.

* Revert "Event: Add radio click triggering tests"

This reverts commit 5f35b5b.

* Tests: add test for passing trigger data to radio click handler

Close gh-3581
Fixes gh-3579

* Build: Updating the master version to 3.2.2-pre.

* CSS: retrieve inline style before computed

- Fixes an issue with getting computed style on detached elements

* Revert "Build: Updating the master version to 3.2.2-pre."

This reverts commit 066bd86.

* Build: Updating the master version to 3.2.2-pre.

* Tests: Fix incorrect assert name for ensure_iterability_es6

Closes gh-3584
Ref bb026fc.

* Docs: Update links to HTML spec for stripAndCollapse (#3594)

* Offset: Use correct offset parents; include all border/scroll values

Thanks @anseki

Fixes gh-3080
Fixes gh-3107
Closes gh-3096
Closes gh-3487

* Core: Update isFunction to handle unusual-@@toStringTag input

Ref gh-3597
Fixes gh-3600
Fixes gh-3596
Closes gh-3617

* Tests: Improve offset test setup and labels

Hopefully this fixes iOS testing: http://swarm.jquery.org/job/5226

Ref 1d2df77
Closes gh-3641

* Tests: Be even more async for iOS

Ref 1d2df77
Closes gh-3643

* Tests: Attach test iframes to the body for visibility-dependent code

Ref 1d2df77
Closes gh-3645

* Tests: Allow a mock QUnit.test for perfect testIframe fidelity

Ref 1d2df77
Closes gh-3647

* Tests: Prepend test iframes for even *more* consistency

Ref 1d2df77

* Tests: Reset iframe window scroll after updating html/document position

Ref 1d2df77
Closes gh-3649

* Tests: Add debugging to investigate iOS failures

Ref 1d2df77

* Tests: Keep iframes visible in TestSwarm

Ref 1d2df77

* Tests: Adjust by actual scroll position, rather than expected

Ref 1d2df77

* Tests: Clean up offset debugging

Ref 1d2df77
Ref c0edd8d

* Tests: Correct expected assertion count

Ref e94b5b0

* Tests: Revert some testIframe changes to fix dimensions tests

Ref c0edd8d

* Revert "Tests: Revert some testIframe changes to fix dimensions tests"

This reverts commit c4368a9.

* Tests: Revert some testIframe changes to fix dimensions tests

Ref c0edd8d

* CSS: Drop the float mapping from cssProps

Firefox 35 and newer support style.float directly.

Closes #3569

* Docs:Tests: Update IE/Edge-related support comments & tests

Closes gh-3661

* Build: Test on Node.js 8, stop testing on Node.js 7

* Tests: minor typos

Close gh-3671

* Dimensions: Include scroll gutter in "padding" box

Fixes gh-3589
Closes gh-3656

* Deferred: fix memory leak of promise callbacks

Fixes gh-3606
Closes gh-3657

* Build: update node dependencies; commit package-lock.json

- Also ignore yarn.lock
Close gh-3669

* Build: Update sinon, husky, and qunitjs

* Build: fix uglify options for uglify update

- Uses new typeofs option for compression
- See mishoo/UglifyJS2#2198

Close gh-3710

* Event: `stopPropagation()` on native event-handler

Fixes gh-3693
Close gh-3694

* Core: Deprecate jQuery.isWindow

Fixes gh-3629
Close gh-3702

* Test: ensure position/offset return mutable objects

Fixes gh-3612
Closes gh-3695

* Revert "Offset: Resolve strict mode ClientRect "no setter" exception"

This reverts commit 3befe59.

* Offset: fix error from bad merge in #3695

* Dimensions: Detect and account for content-box dimension mishandling

Fixes gh-3699
Closes gh-3700

* Support: Properly check for IE9 absolute scrollbox mishandling

Ref gh-3589
Fixes gh-3699
Fixes gh-3730
Closes gh-3729

* Tests: Try extra hard to control focus

Ref gh-3732

* Tests: Abort focus tests when the environment doesn't cooperate

Ref gh-3732

* Tests: Reduce the abort timeout for simple focus testing

Ref gh-3732

* Tests: Simulate events when CI hinders use of native ones

Ref gh-3732

* Tests: Account for TestSwarm focus issues

Closes gh-3732

* Ajax: add an ontimeout handler to all requests

Fixes gh-3586
Close gh-3590

* Dimensions: Improve offsetWidth/offsetHeight fallback

Fixes gh-3698
Fixes gh-3602
Closes gh-3738

* Tests: Replace non-ASCII whitespace in source code

* Dimensions: Don't trust non-pixel computed width/height

Fixes gh-3611
Closes gh-3741

* Build: Fix comment typo

Closes gh-3747

* Build: Update my name in .mailmap

I got married! 🎉

* Build: Update my name in ATHORS.txt

I forgot .mailmap isn't everything.

* Tests: Update path calculation

Fixes gh-3756
Closes gh-3757

* CSS: Avoid unit-conversion interference from CSS upper bounds

Fixes gh-2144
Closes gh-3745

* Tests: Update lineHeight adjustments to give Android more slop

* CSS: Detect more WebKit styles erroneously reported as percentages

Ref 692f9d4
Fixes gh-3777
Closes gh-3778

* Build: Update to Babel 7, use for-of plugin instead of preset-es2015

Closes gh-3786

* Build: Drop cross-spawn, use child_process.spawn shell option

* Build: increase timeout in Promises/A+ tests 10 times

The promises-aplus-tests sets up a default 200 ms Mocha timeout. This makes
our tests randomly fail on Jenkins. 2 seconds will be safer.

Closes gh-3791

* Build: Remove package-lock.json, add it to .gitignore

npm 5, even the version included in the latest Node.js 8.5.0 re-generates
`package-lock.json` on each install. And when it does on a system that doesn't
support all the optional dependencies that are supported on the OS where the
lockfile was generated, it removes those optional deps from the lockfile.

The effect is that everyone firing `npm install` on our repo on any OS other
than macOS will immediately get a dirty state of the repo as the `fsevents`
dependency subtree gets removed from `package-lock.json`. That's a really bad
experience.

This commit removes package-lock.json from the repository and adds it to
.gitignore. We'll start committing the file again once the issue is resolved
on npm's part.

Fixes gh-3792

* Tests: Make Node tests work for paths with spaces in them

Without this patch Jenkins tests fail as jQuery job names there contain spaces,
e.g. "jQuery Core".

Closes gh-3821

* Tests: Add Safari 11 support test results

* Build: Test on Node.js 9

Closes gh-3840

* Tests: Add iOS 11 support test results

* Manipulation: Reduce size by eliminating single-use variable

Closes gh-3851

* CSS: Correctly set support properties with non-default zoom

Fixes gh-3808
Closes gh-3872

* Docs: Create CODE_OF_CONDUCT.md

Close gh-3865

* Tests: Add support for running unit tests via grunt with karma

- Update QUnit to 1.23.1
- Remove unused dl#dl from test/index.html
- Remove unused map#imgmap from test/index.html
- Ensure all urls to data use baseURI
- Add the 'grunt karma:main' task
  - customContextFile & customDebugFile
- Add 'npm run jenkins' script

Close gh-3744
Fixes gh-1999

* Build: Only run browser tests in one Node version on Travis

Ref gh-3744
Closes gh-3894

* Core: make camelCase function available only for internal usage

Close gh-3604
Fixes gh-3384

* Core: adjust data tests to ensure proper camelCasing

- Add back camelCase to the public object (deprecate not remove)
Ref #3384

* Core: deprecate jQuery.now

Fixes gh-2959
Close gh-3884

* Core: deprecate jQuery.proxy (not slated for removal)

Fixes gh-2958
Close gh-3885

* Manipulation: use `.children` to select tbody elements

- selectors beginning with a child combinator are not valid natively.
  This fixes the tests when using selector-native.js

* Attributes: allow array param in add/remove/toggleClass

+30 bytes instead of +182

Thanks to @faisaliyk for the first pass on this feature.

Fixes gh-3532
Close gh-3917

* Ajax: add unit test for getScript(Object)

Fixes gh-3736
Close gh-3918

* Tests: only run ontimeout test if ontimeout exists

Fixes gh-3742
Close gh-3919

* Build: Fix UglifyJS output in Android 4.0; update uglify

- Thanks to @mgol for first pass

Fixes gh-3743
Close gh-3920

* Tests: fix function reference for unbinding

Ref gh-2958

* Build: Remove CRLF line endings to fix builds on Windows

Close gh-3929

* Core: deprecate jQuery.isFunction

Fixes gh-3609

* Event: Move event aliases to deprecated

Fixes gh-3214

* Ajax: Don't process non-string data property on no-entity-body requests

Fixes gh-3438
Closes gh-3781

* Core: deprecate jQuery.isNumeric

Fixes gh-2960
Closes gh-3888

* Tests: fix weird failure in Edge 16 CSS

Fixes gh-3866
Close gh-3932

* Tests: fix weird flaky attributes test in Edge 16

Fixes gh-3867
Close gh-3931

* Core: deprecate jQuery.type

Fixes gh-3605
Close gh-3895

* Tests: fix number of expected assertions in basic core

* Tests: temporarily require sudo access for karma:main on travis

- This should fix the broken travis build on Node 8
- See travis-ci/travis-ci#8836

* Tests: correctly set sudo in travis config, not karma config

* Manipulation: Add support for scripts with module type

Fixes gh-3871
Close gh-3869

* Tests: fix tests in AMD mode

* Tests: ensure that module assertions run on supported browsers

- Also fixes tests for karma, where the URL for the module is different

Ref gh-3871

* Filter: Use direct filter in winnow

for both simple and complex selectors

Fixes gh-3272
Closes gh-3910

* Build: Add "-debug" suffix to name of karma debug tasks

Ref gh-3922
Close gh-3936

* Tests: skip test with invalid selector for selector-native tests

* Release: add new authors to AUTHORS.txt

* Release: update version to 3.3.0-pre

* Build: Updating the master version to 3.3.1-pre.

* Build: Updating the master version to 3.3.2-pre.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 18, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.