[CSS2.1] Margin-collapsing rules in 8.3.1 don't match reality

(Filed as issue 178 as soon as this email hits the archives.)

In section 8.3.1 of CSS 2.1 the margin-collapsing rules are explained.
 In particular, the third-from-the-bottom paragraph explains how to
deal with the situation when a clearing element has self-adjoining
margins and a subsequent sibling's margins collapse through it.
However, it appears that this rule doesn't reflect implementations,
which seem to be consistent in their treatment of several test-cases.

Check out the test-cases here:
http://test.csswg.org/source/contributors/microsoft/incoming/marginandclear.htm

In particular, check out the 2nd through 4th test-cases.  They all
share an identical structure, with the only difference between the
margin on the second child element:

<div style="border:5px solid purple; width:300px;">
  <i style="float: left; height: 100px; width:20px; background:yellow;"></i>
  <b style="display:block; clear: left; outline:1px solid orange;
margin-top:0px;"></b>
  <u style="display:block; height: 50px; margin-top: 50px;
background:blue;"></u>
</div>

(In the images, the <i> is the floating yellow block, the <u> is the
blue block on the bottom, and the <b> is the orange outline hovering
in the center.)

The simplest case is where <b> has margin-top:100px.  Then no
clearance is applied, and the situation is simple - the <u>'s margin
collapses through the <b>, making the two elements flush with each
other.

Per spec, this rendering should be maintained for any margin-top value
from 0px to 100px.

Per reality, though, it appears that every implementation implements
this in a different, but consistent, way, as illustrated by the 2nd
and 3rd test cases.

In the 2nd test case, the <b> has margin-top:0, and so gains 100px of
clearance to move it below the float.  The <u> then sits 50px below
the <b>.  In the 3rd test case, the <b> has margin-top:25px, and so
gains 75px of clearance.  The <u> then sits 25px below the <b>.

When I was talking with Arron and his coworker about these test-cases,
it appears that they implement this by using a concept of "flow" that
can be "consumed" by elements.  New elements are placed relative to
this flow line.  In this particular case, the clearance added to <b>
consumes some flow (moving the positioning line downwards), and then
<u>'s margin collapses through <b>'s (in some cases only *partially*
collapsing, such as in the 3rd test case) and positions its margin
edge against where the flow line is.

I doubt we want to rewrite things to that degree to handle this case,
since it sounds like the sort of thing that would cause cascading
changes throughout the spec.  I think we can handle this using only
concepts that already exist, though.

I'll address these in the next email, where I discuss a different
test-case that exposes a more general problem with the spec's
margin-collapse rules.

~TJ

Received on Friday, 30 July 2010 18:48:24 UTC