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

Width and height functions are no longer symmetric for scrollable elements since 3.2.0 #4255

Open
JoolsCaesar opened this Issue Dec 7, 2018 · 2 comments

Comments

Projects
None yet
3 participants
@JoolsCaesar
Copy link

JoolsCaesar commented Dec 7, 2018

Description

In jQuery 3.0.0 the width and height functions were changed to respect things like css zoom. This change ended up being reverted in 3.1.0.
#3193
One of the reason it was reverted was that it broke the symmetry of the API.

Then in 3.2.0 the width and height functions were changed to return the width/height without scrollbars (clientWidth/clientHeight). This too has broken the symmetry of the API:
https://jsfiddle.net/JoolsCaesar/r0vxq926/
Note: I'm seeing this behaviour in Chrome, IE, Edge and Opera but not Firefox

Is this a bug?
If it's an intentional change it might be worth adding something to the documentation as there's no mention of scrollbars in the width and height API and people might assume that these function still work as symmetric getters and setters. It also seems a little odd that this is no longer consistent across browsers.

Is there a way to get the old value?
Previously I would call $elem.width() if I wanted the width ignoring scrollbars and $elem[0].clientWidth to get the width taking scrollbars into account. Now they both do the same thing and I'd like to know how to get at the former.

Also the API (http://api.jquery.com/width/) states:

Note that .width() will always return the content width, regardless of the value of the CSS box-sizing property.

That doesn't seem to be true, because setting box-sizing to border-box causes it to ignore the scrollbars, essentially reverting to the old behaviour:
https://jsfiddle.net/JoolsCaesar/r0vxq926/5/

Link to test case

New asymmetric API:
https://jsfiddle.net/JoolsCaesar/r0vxq926/
Old behaviour (jQuery 3.1.1):
https://jsfiddle.net/JoolsCaesar/r0vxq926/1

@timmywil

This comment has been minimized.

Copy link
Member

timmywil commented Dec 7, 2018

Thanks for opening an issue. There have already been some changes made to dimensions on the master branch. The scrollbars are ignored in .width(), except in Firefox, and included in .outerWidth(). Turns out that only Firefox includes the scrollbars in getComputedStyle, but offsetWidth includes it in all browsers. Our jquery-git builder is currently down, so I put the most recent build on Dropbox. https://jsfiddle.net/timmywil/bcto3vmu/16/.

@gibson042

This comment has been minimized.

Copy link
Member

gibson042 commented Dec 7, 2018

Ugh, I am so sick of these scrollbar-related dimensions issues. What's happening here is that in the affected (i.e., non-Firefox) browsers, elements with box-sizing: content-box do not include scroll gutters in computed height and width (e.g., your "800px" value gets read back as "785px"). We can add a support method for detecting this, and we can determine scroll gutter width using the offset* trick from #3656, but we're still left with a round-tripping dilemma that's directly related to whether or not .width and .height (which are documented to get computed $dimension and set content $dimension—the former apparently a documentation bug) should include scroll gutters as part of content box dimensions. The spec text on this point is not nearly clear enough, although everything still reads to me like scroll gutters do reduce the dimensions of an element's content box.

I'd like to make it so that jQuery .width and .height always exclude scroll gutter, but that seems to be impossible for box-sizing: border-box elements, and backwards-incompatible anyway. So I guess we should go the other way, patching up other browsers to agree with Firefox and include the scroll gutter even though padding can separate it from the rest of the content box. IOW, neither a scroll gutter nor box-sizing should affect the value returned from .width() or .height() in any browser, and it should safely round-trip everywhere.

Resulting relationship with the CSS box model:

  • .width and .height: content box, inclusive of scroll gutters
  • .innerWidth and .innerHeight: padding box, inclusive of scroll gutters
  • .outerWidth and .outerHeight: border box or margin box, inclusive of scroll gutters

Maybe someday we'll find a way to properly deal with scrollbars, but right now I'm ready to just give up.

@timmywil timmywil added this to the 3.4.0 milestone Dec 10, 2018

@timmywil timmywil removed the Needs review label Dec 17, 2018

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