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

On Fri, Jul 30, 2010 at 10:29 PM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
> 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.


Hmm. I don't think we need to talk about partially-collapsed margins
to explain what we see here. The margins collapse normally. The
outline reveals the position of the border edge of the element, which
according to the spec is computed as "if the element had a non-zero
bottom border" and so it is only affected by the top margin, not by
the bottom one. Compare:
  http://brunildo.org/test/test/CollapsedThroughPosition1.html  (the
test case you mention, just slightly rewritten)
with
  http://brunildo.org/test/test/CollapsedThroughPosition2.html
where I've simply added a parent to the collapsed through element. Now
its position is 2em below the first div, because the presence of the
parent changes the rule used to determine its position, now its top
border edge "is defined to be the same as the parent's".

So, I don't see here anything not interpretable according to the current spec.


> 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.


I believe this case can be interpreted normally as well, at least in
Firefox (that I believe is correct), I haven't checked the others.
There is no need to say that there is partial collapsing. Of course
the clearance is not a margin, so there is no collapsing with it. The
total collapsed margin is 40px, the position of the divs is determined
by the rule "as if they had a non-zero bottom border (20px of these
total 40px are behind the float).  The addition of a parent to the
last two divs moves the position of the green one in the same place of
the red one.


Bruno

-- 
Bruno Fassino http://www.brunildo.org/test

Received on Wednesday, 4 August 2010 06:08:02 UTC