W3C home > Mailing lists > Public > www-style@w3.org > March 2000

Very bad errors in positioning

From: Matthew Brealey <webmaster@richinstyle.com>
Date: Mon, 20 Mar 2000 11:25:52 -0800
Message-ID: <38D67B40.1091@richinstyle.com>
To: www-style@w3.org
<q>
'top'
...
This property specifies how far a box's top content edge is offset below
the top edge of the box's containing block.
</q>

This surely must be the worst error in CSS. Firstly, it is not the
content edge but the margin edge and secondly it is not necessarily the
top edge of the containing block - if it is a relatively positioned
element it is an offset relative to its normal position.

Correct would be 'For absolutely positioned elements, this property
specifies the offset of the element's top margin edge below the top edge
of the containing block.'

For relatively positioned elements, there are serious problems. Since
top: x is equivalent to bottom: -x, there are undefined conflicts in CSS
- what does <div style="top: 50px; bottom: -60px"> do? There are very
bad problems here that need urgent public resolution.

In addition there are also pretty catastrophic errors relating to the
way that the horizontal formatting of absolutely positioned elements is
determined. It is postulated that LHS == width of containing block, and
yet 

<blockquote>
If the element has 'position: absolute', the containing block is
established by the nearest ancestor with a 'position' other than
'static', in the following way:
1. In the case that the ancestor is block-level, the containing block is
formed by the padding edge of the ancestor.
2. In the case that the ancestor is inline-level, the containing block
depends on the 'direction' property of the ancestor:
A. If the 'direction' is 'ltr', the top and left of the containing block
are the top and left content edges of the first box generated by the
ancestor, and the bottom and right are the bottom and right content
edges of the last box of the ancestor.
B. If the 'direction' is 'rtl', the top and right are the top and right
edges of the first box generated by the ancestor, and the bottom and
left are the bottom and left content edges of the last box of the
ancestor.
</blockquote>

And thus we have in case 1 that the padding edge of the ancestor is the
containing block, but still we sum the LHS of the equation to 'width'.
Therefore the correct equality in this case is LHS == padding width of
the containing block. In case 2 the statement is that if the ancestor is
a relatively positioned inline-level element (since all absolutely
positioned elements are block-level, so the implication is necessary)
the containing block is the top and left content edges of the first box
and right and bottom of the last box. Therefore the correct equation
here is LHS == distance from the top left of the first box generated by
the ancestor to the bottom right of the last box generated by said
ancestor. E.g., in:

<p>
<span style="position: relative">
Relatively positioned content that spans
several lines
</span>
</p>

the width is from the left of the first box (viz. the 'R') bottom right
of the last box (the 's') (this seems a little strange, but the problems
are not insurmountable).

In addition, the formula for the value for vertical properties on
absolutely positioned elements is badly wrong. The current formula sums
the LHS to the height of the containing block, which creates a
performance problem in that the whole of the containing block (typically
BODY) must be rendered before the absolutely positioned element can be
placed. Since absolutely positioned elements are often absolutely
positioned at the top of the canvas, this is clearly impratical. 

To the current rules I would add the proviso that 'If 'bottom' is set to
auto, then the user agent need not sum the values to the height of the
containing block (which usually means that the user agent must have
rendered the whole of the containing block), but may simply render the
element at the distance specified by 'top' below the top edge of the
containing block, since the result would be exactly the same.'

Furthermore:

<blockquote>
top' + 'margin-top' + 'border-top-width' + 'padding-top' + 'height' +
'padding-bottom'
     + 'border-bottom-width' + 'margin-bottom' + 'bottom' = height of
containing block 

(If the border style is 'none', use '0' as the border width.) The
solution to this constraint is reached through a number of substitutions
in the following order: 

   1.If 'top' has the value 'auto' replace it with the distance from the
top edge of the containing block to the top margin edge of a
hypothetical box that would have been the first box of the element if
its 'position' property had been 'static'. (But rather than actually
computing that box, user agents are free to make a guess at its probable
position.) The value is negative if the hypothetical box is above the
containing block. 
   2.If both 'height' and 'bottom' are 'auto', replace 'bottom' with 0. 
</blockquote>

It is stated here that if 'height' and 'bottom' are both auto, bottom is
replaced with 0. This is very badly wrong. For example, take <DIV
style="position: absolute; top: 100px">Some text</DIV>. In this case,
since 'height' and 'bottom' are both auto, bottom is replaced by 0. This
leaves the only auto value as 'height', so the conclusion is that the
height is the height of the containing block - 100px. For a typical
document that is 10,000 pixels high, this gives a height of 9,900 pixels
for an element whose height really should only be the height of its
content (i.e., one line box, assuming that 'Some text' can be formatted
as a single line).

In addition, the statement that 'auto' be replaced 'with the distance
from the top edge of the containing block to the top margin edge of a
hypothetical box that would have been the first box of the element if
its 'position' property had been 'static'. (But rather than actually
computing that box, user agents are free to make a guess at its probable
position.) The value is negative if the hypothetical box is above the
containing block.' is also wrong. In particular, the issue of the first
box of the element does not seem correct - surely it should be the top
margin edge of the element itself.

Furthermore, the specification is also wrong in that it fails to
consider margin collapsing. For example, take 
<div style="margin-bottom: 100px">
Content
</div>
<div style="margin-top: 50px; position: absolute">
Content
</div>

The unambiguous _intent_ is to place the content of the element in the
same place as it would have been but for the position: absolute
declaration. The effect, however, is to place the top margin edge at the
place it would be. The margin edge is here normally:

-------- Margin edge





------- Content edge, at 100 pixels down, due to margin collapsing


So if we place the margin edge at the place it would normally be, the
effect is this:

-------- Margin edge

------- Content edge, at 50 pixels down, due to absolute margins not
collapsing

PS I gather that a large number of errors in positioning have already
been discovered behind closed doors, so I am sorry if this message
repeats any of them.

----------------------------------------
Please visit http://www.richinstyle.com
Featuring:  CSS bug guides (more than 1000 CSS bugs) CSS Masterclass
HTML 4 guide    CSS 1 guide    CSS 2 guide   Web-safe colorizer 
CSS bug table     More than 300 CSS test pages
Received on Monday, 20 March 2000 06:22:40 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 27 April 2009 13:54:04 GMT