Closed Bug 34398 Opened 26 years ago Closed 24 years ago

offsetParent and offsetTop and offsetLeft properties of descendant children appear to be incorrect

Categories

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

defect

Tracking

()

RESOLVED FIXED
mozilla0.9.7

People

(Reporter: joe, Assigned: jst)

References

Details

(Keywords: dom0, testcase, Whiteboard: [HAVE FIX])

Attachments

(4 files)

The properties offsetLeft, offsetTop, offsetWidth, and offsetHeight (implemented as a result of bug #9844), do not give accurate values. I can't make any sense at all out of the values I get, but they are not always in sync with the values from corresponding CSS styles, nor are they correct when the CSS style is set to "auto". I'll attach some examples soon to demonstrate the errors.
Blocks: 34497
Hmm... I had been using build 2000031306 for all my testing, but I just switched to 2000040415 and I now seem to be getting valid results from the offset* properties... The only exception is when an element's top/left is outside of it's parent's boundaries... in which case I get a 0 for offsetWidth/offsetHeight... however, this is really a bug in the CSS2 spec, not Mozilla. I'll re-state my case against the CSS2 spec. When width/height are == "auto", the spec says they should be calculated to be the width/height of the containing block. This is clearly impractical because then you have no way to make a positioned block element "snap" to the size of it's content. Please somebody tell the W3C to find a solution to this problem before Mozilla is released to the masses. They won't listen to a little peon like me, but without this feature, people trying to calculate width/height are going to get flustered when they see what Mozilla churns out.
troy, please have a look at the CSS2 issues Joe brought up here.
jst, the CSS2 issues concerning positioning not being backwards compatible with IE and Navigator are being discussed with the CSS WG. We have all agreed to change the existing rules, and I'm waiting for the new errata to be released before changing our layout code
One specific problem with offsetLeft and offsetTop, which Vidur has already acknowledged in bug #9844, is that the offsetParent is always document.body, and therefore, offsetLeft and offsetTop are really clientLeft and clientTop. So, one thing that needs to be done is that offsetParent must be calculated to be parentNode, and then offsetLeft and offsetTop should be properly calculated from the distance from their parentNode. In addition, it wouldn't hurt to take the current behavior and move it into variables called clientLeft and clientTop. IE has such variables, but they are completely useless (bug perhaps, or bad intentions?) and don't give the expected results.
Confirming. troy@netscape.com - any news here? Gerv
Status: UNCONFIRMED → NEW
Ever confirmed: true
attinasi: Could you take a look at Joe's comment dated 2000-04-06 16:13?
I looked over Joe's comments from 2000-04-06 16:13. I don't have too much to add, but I will say that the we definitely need to calculate the offsetParent correctly and thus get the offset* properties to be correct. I would shy away from doing the clientLeft/clientTop stuff unless it is part of the DOM spec, however. Propietary extensions make me queasy (especially when they are not for compatibility). As one of the new CSS-layout reps I'll see where the issue left off in the working group - it looks like Troy was waiting for the spec to be updated before putting the code into layout.
What rules does IE use to do this? (How does it calculate offsetParent? Are offsetLeft, etc., always up to date?) Is there any draft of a spec that has these properties?
Target Milestone: --- → Future
This bug has been marked "future" because the original netscape engineer working on this is over-burdened. If you feel this is an error, that you or another known resource will be working on this bug,or if it blocks your work in some way -- please attach your concern to the bug for reconsideration.
Status: NEW → ASSIGNED
*** Bug 48448 has been marked as a duplicate of this bug. ***
I noticed this on MacOS9, too, so Platform=All. Changed summary to have more keywords to make it easier to avoid more duplicates.
OS: other → All
Hardware: PC → All
Summary: offset* properties give innaccurate values → offsetParent and offsetTop and offsetLeft properties of descendant children appear to be incorrect
*** Bug 64925 has been marked as a duplicate of this bug. ***
So what's the deal here? Could someone whip up a minimal testcase that shows the problem? That would be very helpful.
I suggest that you take a look at the attachments given in bug #48448 which I filed earlier. This should give you a good start.
I'm submitting an example file (offsetExample1.html) which was run with mozilla build ID: 2001012604 (on a Windows 98 machine) and shows that the offsetParent, offsetLeft, and offsetTop values are totally incorrect. The offsetWidth and offsetHeight values appear to be correct. Both tab elements are children of the container DIV called 'slab'. Clicking on either tab reports the values that are found. Compare these values to the CSS positioning that is given to these elements.
At the moment, el.offsetLeft seems to be equivalent to what the W3C method document.defaultView.getComputedStyle(el,null).getPropertyValue("left") yields. (Similarly for the other offset* properties.) I think this is okay and should not be changed. However, this means giving up strict IE-compatibility, since for IE el.offsetLeft and el.currentStyle.left can differ. The reason for this is that, in IE, an element's offsetParent is either the next positioned element in the parentNode hierarchy, or the next table in that hierarchy. I can see no reason to include tables here, and since there isn't even an agreement between IE4, IE5 and IE5.5 on how to deal with the table case, I guess not many people actually use this. So I would suggest to let offsetParent always be the next positioned element, keeping the equivalence to the computed CSS-values.
Keywords: dom0
offsetLeft and offsetTop is used quite frequently in TurboTax for the Web and I detest having to branch the code to handle the differences between browser for something simple as getting positional information.
This bug seems to be related to #81290 About the use of offset* in current applications I'd say that it is very common. I cannot think of one IE DHTML application that does not use these. I also agree that the result should be the distance from the ancestor defining the coordinate system (just like for CSS). About Joe Hewitt's comment about clientLeft/Top: These properties are a bit tricky... It took me years before I finally figured out what they were used for. offsetLeft gives the distance from the inner edge of the container, clientLeft gives the distance between the containers inner edge and outer edge, giving you the width of the border. See: http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/clientLeft. asp The clientLeft property might not be needed because one could use document.defaultView.getComputedStyle(el, null).getPropertyValue ("borderLeftWidth") instead. Maybe it is need for system with the scroll bars on the left side of a container? By the way is there any plan to allow the usage of element.currentStyle.propertyName for convenience. I just find the W3C way to be to clumsy to use in real life.
I would like to kindly ask that the testcases for this bug be run again now that bug 81290 has been fixed. Erik Arvidson already acknowledged in another bug that the current offset* properties seemed to be good and consistent, with some luck we could also get rid of this one at the same time. Thank you in advance, Fabian.
Keywords: testcase
Could someone take a look at tables in regard to these offset properties? Both the TABLE and TD can act as an offsetParent. This seems to have been overlooked.
Attached patch Proposed fix.Splinter Review
Trying for mozilla0.9.7
Target Milestone: Future → mozilla0.9.7
Whiteboard: [HAVE FIX]
Comment on attachment 57315 [details] [diff] [review] Proposed fix. Is it just me or did you forget to include nsGenericHTMLElement.h in the diff? > >- if (tag.get() == aOffsetParentTag || content == docElement) { >+ if (tag == nsHTMLAtoms::body || content == docElement) { > done = PR_TRUE; > why don't you call IsOffsetParentTag(tag) here? If the above change is on purpose, then shouldn't you remove nsHTMLAtoms::body from IsOffsetParentTag or put it at the end of the conditionals since the cases where tag == nsHTMLAtoms::body are already handled by the above code? r=fabian if my question is answered :-)
Attachment #57315 - Flags: review+
You forgot <th> which is just as valid as <td> is.
Fabian, the first case where we check for tag == nsHTMLAtoms::body is to make sure the offset parent of the body element is null, we don't want to check for table, td, or th there. The place where we do use IsOffsetParentTag() we *do* want to check for all the tags listed in IsOffsetParentTag(). Neil, good catch, new patch coming up.
Attachment #57315 - Flags: needs-work+
Attachment #58824 - Flags: review+
Fix checked in.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: