- From: Mike Wilson <mikewse@hotmail.com>
- Date: Fri, 14 Mar 2008 23:04:55 +0100
- To: "'Www-style'" <www-style@w3.org>
Hi Anne, I think this is an interesting (although somewhat animated ;-) discussion about the offset properties and I think Garrett is bringing up some good points. I have studied some of the differences between the various approaches and made some comparison tables below. There are lots of data here so please excuse (and inform me) if something is not correct. The HTML file used for testing is at the end of this mail. Explanation of labels: - IE7/FF2: tested in Internet Explorer 7 / Firefox 2 - CSSOM: http://dev.w3.org/csswg/cssom-view, 11 March 2008 - [CB]: Containing Block according to CSS 2.1 - simple?: the simplest / most natural value if legacy was not to be considered (I realize there may be opinions about this so no flaming please ;-) offsetParent ------------ This is the offsetParent returned for the respective elements in the example file per browser/spec: offsetParent for/in: IE7 FF2 CSSOM [CB] simple? HTML null null null ICB null BODY null null null HTML HTML div1(pos=rel) HTML BODY BODY BODY BODY div2a div1 div1 div1 div1 div1 div2b div1 div1 div1 div1 div1 div3a(pos=abs) div1 div1 div1 div1 div1 div3b div2b div1 div1 div2b div2b Observations: 1) CSSOM differs from IE by letting div1 point to BODY instead of HTML. Q: What was the rationale for this change? (I agree that it is "cleaner" not to special-case children of BODY to instead point to HTML, but IE is the mother of these properties so...) 2) IE points div3b to div2b (as opposed to div1 in CSSOM). In this respect IE matches the rules for Containing Block to determine offsetParent. I have the impression that the offset properties were designed in the "spirit" of Containing Block for consistency with dimensional properties top, left etc. These are interpreted with respect to the CB so it would make sense to let the corresponding offset properties also do this. [The "simple?" column maps the CB algorithm] Q: Did you consider using the CB algorithm for offsetParent and were there any hard problems? Q: Have you considered CSSOM's deviation with IE for div3b above or is it something that needs to be fixed in the spec? offsetLeft (and others) ----------------------- Note: the example file assigns margin, border and padding to all elements including the HTML element. Values of these properties are indicated below in parenthesis (m,b,p) and the body of the table shows the value of offsetLeft: offsetLeft for/in: IE7 FF2 CSSOM simple? HTML(4m,2b,1p) 0 -2* 0 4 BODY(32m,16b,8p) 39** -16* 0 33/HTML div1(4m,2b,1p) 67**/HTML 47*/BODY 67***/BODY 12/BODY div2b(32m,16b,8p) 33 31* 33 33 div3b(4m,2b,1p) 12/div2b 43*/div1 61/div1 12/div2b * The Firefox algorithm seems to be completely different and I have no guess on how to interpret this. ** The BODY=39 and div1=67 values actually are not the distance to the border edge of the |HTML| element but rather the distance to its margin edge or to the viewport's left edge. *** The value 67 is actually not the distance to the border edge of the |BODY| element but rather the distance to the viewport's left edge. Apart from where noted, all offsets in the table add up correctly according to the "padding edge to border edge" rule. Adding some relative positioning, this is what happens: offsetLeft for/in: IE7 FF2 CSSOM BODY left+10px 39->49 -16 0 div1 left+10px 67->77 47->57 67->77 So, to my observations: 3) As can be seen in both tables IE returns useful values for BODY's offsetLeft property while CSSOM hardwires it to 0. Q: What was the rationale for this deviation from IE's behaviour? 4) As can be seen in the upper table, CSSOM returns offsetLeft = 67 for div1, which is the distance to the viewport edge or margin edge of the |HTML| element, even though div1 reports using BODY as offsetParent, thus: div1.offsetLeft = <distance to viewport/HTML> div1.offsetParent = BODY It would be more consistent to use div1.offsetLeft = <distance to HTML> div1.offsetParent = HTML or div1.offsetLeft = <distance to viewport> div1.offsetParent = null or div1.offsetLeft = <distance to BODY> div1.offsetParent = BODY This change from IE's behaviour leads to returning an offsetParent that isn't the element used when calculating offsets, which is inconsistent. Suggestion: use one of the suggested combinations above, probably best to return offsetParent = null or HTML. (This relates to observation 1 above.) [Btw it seems everybody is using margin edge instead of padding edge when measuring from the |HTML| element] Finally, for comparison, the "simple?" column in the upper table shows what offset values would be returned from the simplest possible algorithm without special-casing certain elements. Unfortunately, and as expected, it is not compatible with IE for div1 and up. Best regards Mike Wilson Example file: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title></title> <style type="text/css"> * { border-color: gray; border-style: solid; } html { margin: 4px; border-width: 2px; padding: 1px; } body { font-family: verdana, arial, helvetica, sans-serif; font-size: 77%; margin: 32px; border-width: 16px; padding: 8px; } div { height: 30px; overflow: hidden; text-align: right; } #div1 { position: relative; height: auto; margin: 4px; border-width: 2px; padding: 1px; } #div2a { margin: 32px; border-width: 16px; padding: 8px; } #div2b { height: 60px; margin: 32px; border-width: 16px; padding: 8px; } #div3a { position: absolute; left: 64px; top: 64px; margin: 4px; border-width: 2px; padding: 1px; } #div3b { margin: 4px; border-width: 2px; padding: 1px; } </style> </head> <body> <div id="div1"> <div id="div2a">div2a</div> <div id="div2b"> <div id="div3a">div3a</div> <div id="div3b">div3b</div> div2b </div> div1 </div> </body> </html>
Received on Friday, 14 March 2008 22:05:39 UTC