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

Test case in question:
http://test.csswg.org/source/contributors/microsoft/incoming/AdjacentMarginsTestCase.htm
(ignore the fact that the code is slightly malformed - it doesn't
affect this case).

Reproduction of the code in question:


<body style="border:5px solid purple; width:200px;">
  <div style="height:1em; background:blue;"></div>
  <div style="margin:1em 0 2em; outline:1px solid orange;"></div>
  <div style="height:1em; background:green;"></div>
</body>

(The first and third <div>s are only there to help illustrate the
boundaries of the second <div>'s margin box - they play no real part
in this example.)

The second <div> here has a margin-top of 1em and a margin-bottom of
2em.  It's self-adjoining, so its bottom margin collapses with its top
margin.  Per spec, this should mean that the top margin basically
becomes 2em, and the <div> itself should then be flush with the green
box.

All implementations do something else, though - the <div> has 1em of
space above it, and 1em of space below it.  This is easy to explain as
a partially-collapsed margin - the bottom margin collapses with the
top margin as much as it can (up to the actual size of the top
margin), and then the rest stays below the element.

This also helps to explain the behavior of the cases in the previous
mail.  The simplest way to explain it appears to be that the clearance
takes up actual space *separate from* and above the margin of the <b>
element (and which margins are not allowed to collapse through), and
then the <u>'s top margin collapses upwards with the <b> in the same
way that it does for the test case in this message.

Playing around with the test-case more, this appears to explain
current behavior completely.

Thoughts?  This is a pretty decent change to how we describe both
margin-collapsing and clearance.  But it appears that this is
precisely equivalent to what everyone actually implements.

Here's a more involved version of the earlier test-case:

<body style="border:5px solid purple; width:200px; padding: 0 0 3px;">
 <div style="height:100px; width: 25px; float: left; background:blue;"></div>
 <div style="outline:1px solid orange; margin:20px 0 0; clear: left;"></div>
 <div style="outline:1px solid green;  margin:30px 0 0;"></div>
 <div style="outline:1px solid red;    margin:40px 0 0;"></div>
</body>

Same code, but now we have *three* empty elements with outlines.  The
orange clearing element has 20px of top margin, and so it gains 80px
of clearance.  The green element has 30px of top margin, so 20px of it
collapses upward into the orange's top margin, with the remaining 10px
below the orange.  The red has 40px of top margin, so 20px of it
collapses with the orange's margin, 10px with the green's margin, and
10px left over between it and the green.

This pretty clearly demonstrates that margins collapse only partially,
and that clearance can affect multiple elements after the clearing
element.

~TJ

Received on Friday, 30 July 2010 20:30:38 UTC