Open Bug 255754 Opened 20 years ago Updated 2 years ago

body's offsetTop and offsetLeft values are incorrect when body has borders

Categories

(Core :: DOM: Core & HTML, defect, P5)

x86
Windows 2000
defect

Tracking

()

People

(Reporter: for_mike, Unassigned)

References

Details

(Keywords: testcase, Whiteboard: INVALID?: see comment 10; for workaround, see comment #7)

Attachments

(3 files)

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; MyIE2; .NET CLR 1.1.4322) Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8a3) Gecko/20040813 After the page is loaded, the right-bottom corner gray DIV is visible (must not). Seems that offsetTop and offsetLeft values are incorrect for the body element. Reproducible: Always Steps to Reproduce: 1. Create a page: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML><HEAD><TITLE></TITLE> <script> function getTop(o) { var y = o.offsetTop; while (o = o.offsetParent) y += o.offsetTop return y } function getLeft(o) { var x = o.offsetLeft; while (o = o.offsetParent) x += o.offsetLeft return x } function setPos() { var d1 = document.getElementById('div1'); var d2 = document.getElementById('div2'); d2.style.top = getTop(d1)+'px'; d2.style.left = getLeft(d1)+'px'; } </script> <style> body { border: solid 2px black; } </style> <BODY onload="setPos()"> <div id="div1" style="position:absolute;top:100px;left:100px;width:50px;height:50px;background- color:silver"> Text </div> <div id="div2" style="position:absolute;top:100px;left:100px;width:50px;height:50px;background- color:yellow;z-index:2"> Text2 </div> </BODY></HTML> 2. Load the page. Actual Results: After the page is loaded, the right-bottom corner gray DIV is visible. The DOM Inspector shows that offsetTop and offsetLeft properties are set to the border's width value resulting in incorrect position calculation. Expected Results: The gray layer must not be visible: offsets must be correctly adjusted.
According to Measuring Element Dimension and Location http://msdn.microsoft.com/workshop/author/om/measuring.asp offsetTop value does not include the offsetParent's border. Mozilla tries to follow MSIE's DHTML object model here. I checked your code with a few modifications, and the offset you see comes from the border-width of the body node.
Whiteboard: INVALID
Component: DOM: Level 0 → DOM: Mozilla Extensions
I must say that MSIE 6 treats abs. pos. elements differently as the picture given at http://msdn.microsoft.com/workshop/author/om/measuring.asp I opened a bugfile (bug123313) at Opera on this myself a few months ago. So I feel awkward here. http://www10.brinkster.com/doctorunclear/BrowserBugsSection/Opera7Bugs/OffsetParentRelatedBugs.html Instructions: Mouse over the white-background abs. pos. <p> and results will show: offsetParent tagName in Mozilla 1.8a3 and Opera 7.54: BODY offsetParent tagName in MSIE 6 SP1a: HTML So, there is a discrepancy here on the way to support offsetParent. CSS2.1 says: "The containing block for a positioned box is established by the nearest positioned ancestor (or, if none exists, the initial containing block)" http://www.w3.org/TR/CSS21/visuren.html#q28 offsetParent according to MSDN: Retrieves a reference to the container object that defines the offsetTop and offsetLeft properties of the object. offsetTop Property according to MSDN: Retrieves the calculated top position of the object relative to the layout or coordinate parent, as specified by the offsetParent property. Both MSDN definitions for offsetTop and offsetParent are somewhat circular.
Whiteboard: INVALID
(In reply to comment #2) http://www10.brinkster.com/doctorunclear/BrowserBugsSection/Opera7Bugs/OffsetPar entRelatedBugs.html > Instructions: Mouse over the white-background abs. pos. <p> and results will show: > offsetParent tagName in Mozilla 1.8a3 and Opera 7.54: BODY > offsetParent tagName in MSIE 6 SP1a: HTML > So, there is a discrepancy here on the way to support offsetParent. Taking into account the discrepancy between offsetParent support, I may suppose that Opera 7.54 would also show a part of the gray layer. But it does not, because offsetTop and offsetLeft for the body are zeroes there.
Actual results in Mozilla 1.8a6 build 2004122106: yellow-background div is positioned at coordinate (77, 77) in the content box of the body node. DOM inspector reports that the body node's own offsetLeft and offsetTop is -23px while saying that its own offsetParent is null. That does not make sense. Expected results: yellow-background div should be positioned at coordinate (100, 100) in the content box of the body node. Since offsetLeft, offsetTop and offsetParent are MSIE's DHTML object model properties, then I think Mozilla should follow MSIE 6 here.
Picture of the offsetLeft, offsetTop and offsetParent values of the body node when examining testcase of attachment 169409 [details] in DOM inspector. parentNode is the root element (HTML node) and the offsetParent is (null) but in fact has to be the ICB.
Mikhail, I've reset this bug severity to minor since setting borders on the body node and having to dynamically position an abs. pos. element according to another element's offsetLeft/Top value is rather rare on the web. Adding testcase and clean-report as keywords though. CONFIRMING
Blocks: 196779
Severity: normal → minor
Status: UNCONFIRMED → NEW
Ever confirmed: true
I want to emphasize that there is no problem, no bug if people use function getTop(o) { var y = o.offsetTop; while (o.offsetParent) { y += o.offsetTop; o = o.offsetParent; } return y } instead of function getTop(o) { var y = o.offsetTop; while (o = o.offsetParent) // this instruction creates an unwanted side effect y += o.offsetTop return y } ---- The bug with Mozilla here is that it returns an offsetLeft and offsetTop value for an element that has NO offsetParent node. Expected results: a node should return undefined for its offsetLeft value and undefined for its offsetTop value if an element does not have an offsetParent node (if offsetParent value is null)
Summary: body's offsetTop and offsetLeft values are incorrect when using borders for body → body's offsetTop and offsetLeft values are incorrect when body has borders
(In reply to comment #7) > I want to emphasize that there is no problem, no bug Please forgive me if I prove to be wrong, but IMHO there's something that look silly in the offset properties. Consider the following code: <html> <head> <script> function getTop(o) { var y = o.offsetTop; while (o = o.offsetParent) // this instruction creates an unwanted side effect y += o.offsetTop return y } </script> </head> <body style="margin: 0px;"> <div style="border: 100px solid blue;"><div style="border: 50px solid black;" onclick="alert(getTop(this));">Clickme</div></div> </body> You got an alert 150, which seems correct. Now, add some "position: relative; top: 10px;" on one or another of the div. You immediately loose the border-width of that element in the total count. Please forgive my stupidity if I missed something, but how do we access the screen position of an element if we can't compute it with offsets? "since setting borders on the body node and having to dynamically position an abs. pos. element according to another element's offsetLeft/Top value is rather rare on the web." Well, in my case, the problem is to dynamically set the height of a div according to its top position and the coords of a click event... Regards - Olivier
Sorry for the double post, but what I wrote was unclear and incorrect. The first alert you got is 100 (and not 150), and this makes sense. Now, replace the first div with: <div style="position: relative; top: 10px; border: 100px solid blue; margin: 25px; padding: 25px;"> You'll get 60 (margin+padding+top)... where's the border?
> The bug with Mozilla here is that it returns an offsetLeft and offsetTop value > for an element that has NO offsetParent node. > > Expected results: a node should return undefined for its offsetLeft value and > undefined for its offsetTop value if an element does not have an offsetParent > node (if offsetParent value is null) This bug may be INVALID after all. The problem is that we are following MSIE here and its unique implementation of offsetLeft, offsetTop and offsetParent definitions. On this page, when viewed and tested with MSIE 6 SP2, http://www.gtalbot.org/BrowserBugsSection/MSIE6Bugs/OffsetValues.html the offsetLeft and offsetTop correspond to the body margins and offsetParent returns null. So, IMO, their implementations are incoherent otherwise their definitions are incorrect. Either way, Mozilla can not implement incoherently defined properties which are not even under its control. Mozilla considers border around the body node when measuring offsetLeft and offsetTop; MSIE 6 does not. MSIE 6 considers the margins around the body node when measuring offsetLeft and offsetTop; Mozilla does not. Anyway, I reported the whole thing though at: http://channel9.msdn.com/wiki/default.aspx/Channel9.InternetExplorerBugs so that if they ever better clarify their implementation - which I think is ill-designed - then we can reopen this bug. The workaround is still in comment #7.
Keywords: clean-report
Whiteboard: INVALID?: see comment 10; for workaround, see comment #7
I stumbled across this bug report regarding Firefox: http://www.quirksmode.org/bugreports/archives/2005/08/Border_Bugs_in_Firefox_and_IE.html and http://crp2103.dyndns.org/endpoint/test.html where Chad Plummer says "[Firefox and IE] don't take the border width into account when calculating the offsetTop and offsetLeft JavaScript properties of an element."
http://dump.testsuite.org/2006/dom/style/offset/spec I'm planning on writing something up that completely matches what IE does so every browser can do just that. Of course, there will be some issues I guess with position:fixed etc., but we can work those out.
My planning is over and I have written an application that shows how any browser handles these issues. The application can be found at: http://home.no.net/trosen/bugzilla/CheckPosDim/CheckPosDim.html It was written to document https://bugzilla.mozilla.org/show_bug.cgi?id=387922 which I believe explains this and lots of other layout-related bugs
Marking NORMAL comment #7 is not a workaround for the bug. Finding an element's position is painful. regarding the mentioned comment #12, no browser should even consider to implement it; it's wrong.
Severity: minor → normal
Just wanted to chime in. This bug is still there, and now that IE8 has switched to the same offsetLeft & offsetParent model as Chrome 2, Safari 4, and Opera 9, there at last seems to be a standard developing. When the body does not have position:relative or absolute, FF2 and FF3 put the left edge of the left margin of a position:absolute left:0 top-level element at the left edge of the left padding of the html element, i.e. the element goes inside the html's margin and border, but outside the body's margin and border. As long as this remains the case, the offsetLeft of a position:relative or position:static should include the body element's left border width, but should not include html element's left border width, so that top-level elements with absolute and non-absolute position at the same horizontal location get the same offsetLeft value. Same for offsetTop. FF2 and FF3 unfortunately still have it reversed for the borders - but get it right with the margins. BTW, IE8, Chrome 2, Safari 4, and Opera 9 all put the left edge of the left margin of a position:absolute left:0 top-level element at the left edge of the window, i.e. outside the html's margin and border, and include the margin and border widths of both the html and body elements in the offsetLeft of non-absolute top-level elements.
Attached file test case (deleted) —
I've added a simple test case. Succeeds in IE8, Chrome 2, and Opera 9; fails in FF2 and FF3.
Assignee: general → nobody
QA Contact: ian → general
Component: DOM: Mozilla Extensions → DOM
https://bugzilla.mozilla.org/show_bug.cgi?id=1472046 Move all DOM bugs that haven’t been updated in more than 3 years and has no one currently assigned to P5. If you have questions, please contact :mdaly.
Priority: -- → P5
Component: DOM → DOM: Core & HTML
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: