Closed
Bug 850684
Opened 12 years ago
Closed 7 years ago
offsetLeft / offsetTop get wrong value when offsetParent 's border is set, parent has non-visible overflow, and child is absolutely positioned
Categories
(Core :: DOM: Core & HTML, defect)
Core
DOM: Core & HTML
Tracking
()
RESOLVED
FIXED
mozilla58
Tracking | Status | |
---|---|---|
firefox58 | --- | fixed |
People
(Reporter: yuqingcai, Assigned: bzbarsky)
Details
(Keywords: testcase, Whiteboard: [bugday-20131002])
Attachments
(4 files)
User Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.17 (KHTML, like Gecko) Ubuntu Chromium/24.0.1312.56 Chrome/24.0.1312.56 Safari/537.17
Steps to reproduce:
I created two div element,div1 contain div2,
css source:
div.style1{
margin: 10px;
border: 10px solid #FF0000;
padding: 10px;
left: 10px;
top: 10px;
width: 300px;
height: 300px;
background-color: #FFFFFF;
position: absolute;
overflow: hidden;
}
div.style2{
margin: 10px;
border: 10px solid #00FF00;
padding: 10px;
left: 10px;
top: 10px;
width: 200px;
height: 200px;
background-color: #FFFFFF;
position: absolute;
overflow: hidden;
}
html source:
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="head">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>
find parent
</title>
<link rel="stylesheet" type="text/css" href="/style/common.css" />
<script src="/js/find_parents.js"></script>
</head>
<body>
<div id="div1" class="style1">
<div id="div2" class="style2" onmousedown="showInfo(event, this)">
test...
</div>
</div>
<div id="info" class="infoStyle">
</div>
</body>
</html>
js source:
function getObjOffset(obj, offset) {
if (!obj) {
return ;
}
offset.x += obj.offsetLeft + obj.clientLeft;
offset.y += obj.offsetTop + obj.clientTop;
getObjOffset(obj.offsetParent, offset);
}
function getObjPos(obj, offset) {
getObjOffset(obj, offset);
offset.x -= obj.clientLeft;
offset.y -= obj.clientTop;
}
function showInfo(evn, obj) {
var offset = {x: 0, y: 0};
getObjPos(obj, offset);
var infoObj = document.getElementById("info");
infoObj.innerHTML = offset.x + ", " + offset.y + "<br/>" +
evn.clientX + ", " + evn.clientY;
}
Actual results:
when I run the javascript code, I noticed that the element of div2's offsetLeft and offsetTop get a wrong value, the offsetLeft is 10px, and the offsetTop is 10px。
Expected results:
the div2's offsetLeft /offsetTop should be 20px, it equal div1's margin 10px + div1's left 10px / div1's top 10px. I use the Chrome, IE and safari to confirm it. When I remove the div1's border Property, the rusult is correct.
Comment 1•12 years ago
|
||
Could you add a complete working testcase as an attachment please?
Comment 2•12 years ago
|
||
Comment 3•12 years ago
|
||
Comment 4•11 years ago
|
||
The testcases currently work inconveniently: the numbers appear behind/under the divs.
Component: Untriaged → DOM
Product: Firefox → Core
Updated•11 years ago
|
Whiteboard: [bugday-20131002]
Assignee | ||
Comment 5•11 years ago
|
||
This happens when an abs-pos element has a containing block with a scrollframe. In nsGenericHTMLElement::GetOffsetRect we get true for isAbsolutelyPositioned so don't accumulate offsets going up the tree, but that means that our offsetLeft just ends up being our offset from the _scrolled_ frame (which is the frame tree parent in this case), not from the _scrollframe_. And the offset between the two of them is precisely the border-width of the parent.
Why exactly do we skip the position accumulation for the isAbsolutelyPositioned case?
Flags: needinfo?(matspal)
Assignee | ||
Updated•11 years ago
|
Summary: offsetLeft / offsetTop get wrong value when offsetParent 's border is set → offsetLeft / offsetTop get wrong value when offsetParent 's border is set, parent has non-visible overflow, and child is absolutely positioned
Assignee | ||
Updated•11 years ago
|
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment 6•11 years ago
|
||
I don't know, I only added the !isOffsetParent check there. The !isAbsolutelyPositioned
part dates back to:
1.264 <jst@netscape.com> 2001-06-29 15:44
Fixing bug 81290. The element.offsetXXX properties contained incorrect values when the element is positioned, or a child of a positioned element, this made these properties kinda useless since we were nowhere close to IE wrt the values of these properties. r=pollmann@netscape.com, sr=vidur@netscape.com
http://bonsai.mozilla.org/cvsblame.cgi?file=/mozilla/content/html/content/src/nsGenericHTMLElement.cpp&rev=1.264&root=/cvsroot#843
I get the same result for your test in FF3.6 for example.
Perhaps this was the "correct" result in IE at the time?
Flags: needinfo?(matspal)
Assignee | ||
Comment 7•11 years ago
|
||
Hard to say. Sounds like we should do some testing in the various other edge cases here, unless the spec editor has already done that...
Flags: needinfo?(annevk)
Updated•11 years ago
|
Flags: needinfo?(annevk)
Assignee | ||
Comment 8•11 years ago
|
||
Anne, does removing the needinfo mean that the edge cases have in fact already been tested by someone and what's in the spec matches most implementations?
Flags: needinfo?(annevk)
Comment 9•11 years ago
|
||
Sorry, I removed myself because Simon is the editor these days. I have done testing http://dump.testsuite.org/2006/dom/style/offset/ but the tests are old and browsers have been tweaked I suppose. I had some tool too but I cannot find it.
Flags: needinfo?(annevk) → needinfo?(zcorpan)
Updated•10 years ago
|
OS: Linux → All
Hardware: x86_64 → All
Version: 19 Branch → Trunk
Comment 10•10 years ago
|
||
Both Chrome and IE return '0' in Boris' testcase. Whether this is correct or not, I think it should be fixed, if just for consistency between current browsers.
Assignee | ||
Comment 11•7 years ago
|
||
OK, so I dug through bug 81290 and related bits a bit. It looks to me like the fix for bug 81290 was just wrong. It should have been fixed similar to how bug 375003 was fixed, but not adjusting for the position of the offsetParent itself.
So I think we can in fact just remove that isAbsolutelyPositioned bit. With it removed, we still pass the testcase from bug 81290, now that bug 375003 is fixed.
Try push with that change: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6725632ce1559c1eb8386069278f4e6093b336af
Assignee | ||
Comment 12•7 years ago
|
||
The check for isAbsolutelyPositioned was an old incorrect attempt to fix bug
81290. We have since added the proper fix (not adding offsets of the offset
parent frame) in bug 375003.
MozReview-Commit-ID: 7NgnfrYcs8h
Attachment #8912008 -
Flags: review?(mats)
Assignee | ||
Updated•7 years ago
|
Assignee: nobody → bzbarsky
Status: NEW → ASSIGNED
Assignee | ||
Comment 13•7 years ago
|
||
I filed https://github.com/w3c/csswg-drafts/issues/1832 on the spec here being totally bogus.
Comment 14•7 years ago
|
||
Comment on attachment 8912008 [details] [diff] [review]
Make sure offset* is computed correctly on absolutely positioned kids of relatively positioned elements with scrolllframes and borders
LGTM. r=mats
Attachment #8912008 -
Flags: review?(mats) → review+
Comment 15•7 years ago
|
||
FYI, <colgroup>, <col> and <option>.offsetTop are incompatible with Chrome.
I've filed bug 1403014.
Comment 16•7 years ago
|
||
Pushed by bzbarsky@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/8377625a20c1
Make sure offset* is computed correctly on absolutely positioned kids of relatively positioned elements with scrolllframes and borders. r=mats
Comment 17•7 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox58:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla58
Updated•6 years ago
|
Flags: needinfo?(zcorpan) → needinfo?(emilio)
Comment 18•6 years ago
|
||
Let's track this in https://github.com/w3c/csswg-drafts/issues/1832. I filed https://github.com/w3c/csswg-drafts/issues/3019 for bug 1403014. Boris, you're awesome, thanks for the tests from this bug :)
Flags: needinfo?(emilio)
Assignee | ||
Comment 19•6 years ago
|
||
You're welcome!
Updated•6 years ago
|
Component: DOM → DOM: Core & HTML
You need to log in
before you can comment on or make changes to this bug.
Description
•