-
Notifications
You must be signed in to change notification settings - Fork 20.6k
Description
.position()
method should return a position of element relative to a closest ancestor element that is positioned.
Therefore, for example, if CSS properties top/left
of the element that has position:absolute
are set to that returned position, the element should not move.
But when the ancestor element that is positioned does not exist (i.e. all ancestor elements have position:static
, this is default), a position relative to <html>
element incorrectly is returned.
For example:
https://jsfiddle.net/fqbgy5pq/
Result:
ClientRect top: 63 left: 63
CSS props top: auto left: auto
.position() top: 59 left: 59
Set return value of `.position()` to `top` and `left`, then the element should not move.
ClientRect top: 59 left: 59
CSS props top: 59px left: 59px
.position() top: 55 left: 55
Note: 2px
was lost by this issue, and more 2px
was lost by another issue of .offset()
.
When fixed .offset()
is used:
Result:
ClientRect top: 63 left: 63
CSS props top: auto left: auto
.position() top: 61 left: 61
Set return value of `.position()` to `top` and `left`, then the element should not move.
ClientRect top: 61 left: 61
CSS props top: 61px left: 61px
.position() top: 59 left: 59
.offsetParent()
method that is called by .position()
method returns <html>
when ancestor element that is positioned is not found. Then, .position()
mistakes.
Line 180 in 305f193
return offsetParent || documentElement; |
I think that
.offsetParent()
should return document
or null
in this case.document
means "base of coordinates".null
means "ancestor element is not found".
Also, .position()
method should return coordinates relative to the document in this case.
And also, .position()
method returns incorrect coordinates when <html>
has position:non-static
(i.e. the ancestor element is really <html>
).
For example:
https://jsfiddle.net/wczL6ae5/
Result:
ClientRect top: 63 left: 63
CSS props top: auto left: auto
.position() top: 59 left: 59
Set return value of `.position()` to `top` and `left`, then the element should not move.
ClientRect top: 62 left: 62
CSS props top: 59px left: 59px
.position() top: 58 left: 58
Note: 1px
was added by this issue, and 2px
was lost by another issue of .offset()
.
When fixed .offset()
is used:
Result:
ClientRect top: 63 left: 63
CSS props top: auto left: auto
.position() top: 61 left: 61
Set return value of `.position()` to `top` and `left`, then the element should not move.
ClientRect top: 64 left: 64
CSS props top: 61px left: 61px
.position() top: 62 left: 62
When .offsetParent()
method returned <html>
, .position()
method ignores its offset.
Line 144 in 305f193
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { |
Therefore, if the
<html>
has offset (i.e. margin
), returned value is incorrect.Strange to say, only
border-width
is included in that calculation.Line 150 in 305f193
top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ), |
I think that it might affect scripts that exist if the return value of .offsetParent()
method is changed.
At least, .position()
should be fixed even if .offsetParent()
is not fixed. In this case, .position()
should not use .offsetParent()
, or it should check whether position
is static
when <html>
was returned.
This issue affects .offset()
method because setter of .offset()
uses .position()
.