position() function reports incorrect left offset under Chrome #2237

Closed
zrei opened this Issue Apr 27, 2015 · 14 comments

Comments

Projects
None yet
5 participants
@zrei

zrei commented Apr 27, 2015

Test this
https://jsfiddle.net/Reimu/yu3c361g/2/
under Chrome and other browsers, you will see the left offset reported by position() method is incorrect under Chrome.

The value of left offset under Chrome is the gap between <html> and <body>, not the real left offset of the horizontally centered <div>.

This problem relates only with horizontally centered <div>s, and can be fixed by calculating manually with the marginLeft value of the element's computed style and the gap between <html> and <body>.

Maybe this is due to a possible bug / design choice of Chrome, as there are also some discussion about it on StackOverflow. But I think jQuery is supposed to deal with such difference between browsers.

@alburthoffman

This comment has been minimized.

Show comment
Hide comment
@alburthoffman

alburthoffman Apr 28, 2015

position() does not include the margins. For me, it's kind of reasonable. Because margin is part of the element. For ur example, the victim div locates at left 8px and top 158px, but it has 160.5px left margin and 0px top margin. So the border of it has 168.5px from the left and 158px from the top.

Since you are not asking for position of the border of victim, so ......

position() does not include the margins. For me, it's kind of reasonable. Because margin is part of the element. For ur example, the victim div locates at left 8px and top 158px, but it has 160.5px left margin and 0px top margin. So the border of it has 168.5px from the left and 158px from the top.

Since you are not asking for position of the border of victim, so ......

@zrei

This comment has been minimized.

Show comment
Hide comment
@zrei

zrei Apr 28, 2015

@alburthoffman Thank you for your explanation. Though still my concern is the different behaviors of this method under different browser.

In my view, when using jQuery I shall be exempt of caring for what browser I am facing. As the behavior of this method shows asymmetry and it is not mentioned in the API documentation.

For this very case, I can obtain the correct result after switching to offset method. But that method has its own semantics and the act of switching itself shows some compatibility concern.

My suggestion is this method reporting same value under same browsers. Either subtracting margin value under Chrome, or follow the Chrome way in all cases.

zrei commented Apr 28, 2015

@alburthoffman Thank you for your explanation. Though still my concern is the different behaviors of this method under different browser.

In my view, when using jQuery I shall be exempt of caring for what browser I am facing. As the behavior of this method shows asymmetry and it is not mentioned in the API documentation.

For this very case, I can obtain the correct result after switching to offset method. But that method has its own semantics and the act of switching itself shows some compatibility concern.

My suggestion is this method reporting same value under same browsers. Either subtracting margin value under Chrome, or follow the Chrome way in all cases.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Apr 28, 2015

Member

To report the same value though, we'd need to ignore the margin on the body in Chrome. There really is a margin on the body in Chrome: https://jsfiddle.net/yu3c361g/4/ So how do we rationalize ignoring a value set in CSS?

Member

dmethvin commented Apr 28, 2015

To report the same value though, we'd need to ignore the margin on the body in Chrome. There really is a margin on the body in Chrome: https://jsfiddle.net/yu3c361g/4/ So how do we rationalize ignoring a value set in CSS?

@alburthoffman

This comment has been minimized.

Show comment
Hide comment
@alburthoffman

alburthoffman Apr 28, 2015

This depends on browsers. I tested it in chrome 41 and safari. And they are the same. But in firefox, the left value is different, because the marginLeft is set to 0 in it.

So it will require lots of browser version checking in this function if it has to return a same value.

This depends on browsers. I tested it in chrome 41 and safari. And they are the same. But in firefox, the left value is different, because the marginLeft is set to 0 in it.

So it will require lots of browser version checking in this function if it has to return a same value.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Apr 28, 2015

Member

It seems like the way most pages would fix this is through a CSS reset or normalize? It seems consistent in Firefox for me BTW.

Member

dmethvin commented Apr 28, 2015

It seems like the way most pages would fix this is through a CSS reset or normalize? It seems consistent in Firefox for me BTW.

@zrei

This comment has been minimized.

Show comment
Hide comment
@zrei

zrei Apr 28, 2015

@alburthoffman I think this is because they are all web-kit based, so I guess checking for the phrase 'Web-Kit' in navigator.userAgent is enough ?

@dmethvin It is my honor to have an official reply from you.
As you have mentioned, the problem is Chrome-only. But the margin to be ignored is set by Chrome, not the user.

It comes as a side effect of "margin:0 auto", which browsers like Firefox interprets as directly horizontally center the div, while Chrome by calculating the margin left. If I drop "margin:0 auto" and give a concrete left margin to the div, in both Firefox and Chrome position reports the same 8px left offset.

So is it possible to overload the position method. For example, when I call position(false), it will ignore the margin totally and reports the left offset of the left border ?

After all, as you can see in this case, the left offset I want to know is definitely the gap from the left border of the div to the left boundary of page, excluding any margin.

zrei commented Apr 28, 2015

@alburthoffman I think this is because they are all web-kit based, so I guess checking for the phrase 'Web-Kit' in navigator.userAgent is enough ?

@dmethvin It is my honor to have an official reply from you.
As you have mentioned, the problem is Chrome-only. But the margin to be ignored is set by Chrome, not the user.

It comes as a side effect of "margin:0 auto", which browsers like Firefox interprets as directly horizontally center the div, while Chrome by calculating the margin left. If I drop "margin:0 auto" and give a concrete left margin to the div, in both Firefox and Chrome position reports the same 8px left offset.

So is it possible to overload the position method. For example, when I call position(false), it will ignore the margin totally and reports the left offset of the left border ?

After all, as you can see in this case, the left offset I want to know is definitely the gap from the left border of the div to the left boundary of page, excluding any margin.

@dmethvin

This comment has been minimized.

Show comment
Hide comment
@dmethvin

dmethvin Apr 29, 2015

Member

What I was suggesting is that if you set the margin to zero in all browsers it works fine: https://jsfiddle.net/yu3c361g/8/

Member

dmethvin commented Apr 29, 2015

What I was suggesting is that if you set the margin to zero in all browsers it works fine: https://jsfiddle.net/yu3c361g/8/

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Apr 29, 2015

Member

@dmethvin I still see a discrepancy when the result pane is sufficiently wide, even with your latest fiddle. There is a bug here, but it's in Firefox and we've marked it "cantfix" on our side at least twice before: trac-11110 and trac-11813.

Member

gibson042 commented Apr 29, 2015

@dmethvin I still see a discrepancy when the result pane is sufficiently wide, even with your latest fiddle. There is a bug here, but it's in Firefox and we've marked it "cantfix" on our side at least twice before: trac-11110 and trac-11813.

@gibson042 gibson042 added the Offset label Apr 29, 2015

@alburthoffman

This comment has been minimized.

Show comment
Hide comment
@alburthoffman

alburthoffman Apr 29, 2015

It cannot be fixed in Firefox. It was caused by window.getComputedStyle() in FF. This function doesnot return caculated margins when margins are set to auto.

One problem is to find a way to check if margins are set to auto or not in FF. No clues right now.....

It cannot be fixed in Firefox. It was caused by window.getComputedStyle() in FF. This function doesnot return caculated margins when margins are set to auto.

One problem is to find a way to check if margins are set to auto or not in FF. No clues right now.....

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Apr 29, 2015

Member

This is fixable with another "awesome hack"-style swap, but it might be big: https://jsfiddle.net/yu3c361g/9/

...and if we do it right (with jQuery.cssHooks instead of in .position), then it may get even bigger and almost certainly slower (from multiple reflows).

Member

gibson042 commented Apr 29, 2015

This is fixable with another "awesome hack"-style swap, but it might be big: https://jsfiddle.net/yu3c361g/9/

...and if we do it right (with jQuery.cssHooks instead of in .position), then it may get even bigger and almost certainly slower (from multiple reflows).

@alburthoffman

This comment has been minimized.

Show comment
Hide comment
@alburthoffman

alburthoffman Apr 30, 2015

Awesome!

Just curious about the swap part. why does it need to check marginTop? when marginTop is auto, then it should be 0px, right?

Awesome!

Just curious about the swap part. why does it need to check marginTop? when marginTop is auto, then it should be 0px, right?

@gibson042

This comment has been minimized.

Show comment
Hide comment
@gibson042

gibson042 Apr 30, 2015

Member

Yes, of course. I just got carried away with the copypasta.

Member

gibson042 commented Apr 30, 2015

Yes, of course. I just got carried away with the copypasta.

@timmywil timmywil added the Bug label Apr 30, 2015

@timmywil timmywil added this to the 3.0.0 milestone Apr 30, 2015

@timmywil

This comment has been minimized.

Show comment
Hide comment
@timmywil

timmywil Apr 30, 2015

Member

I guess I'd be in favor of aligning the behavior. The swap is unfortunate, but we can limit its usage to this one case.

Member

timmywil commented Apr 30, 2015

I guess I'd be in favor of aligning the behavior. The swap is unfortunate, but we can limit its usage to this one case.

@alburthoffman

This comment has been minimized.

Show comment
Hide comment
@alburthoffman

alburthoffman Apr 30, 2015

Also, support_marginAuto can be calculated when jQuery starts, don't need to test it every time position is called.

Also, support_marginAuto can be calculated when jQuery starts, don't need to test it every time position is called.

gibson042 added a commit to gibson042/jquery that referenced this issue May 8, 2015

@gibson042 gibson042 closed this in 487d5ca Oct 18, 2015

@dmethvin dmethvin modified the milestones: 1.12/2.2, 3.0.0 Jan 7, 2016

@cssmagic cssmagic referenced this issue in cssmagic/ChangeLog May 18, 2016

Open

jQuery #5

@jquery jquery locked as resolved and limited conversation to collaborators Jun 19, 2018

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