[CSS21] margin-collapse-164 is currently invalid per section 9.5.2

http://test.csswg.org/suites/css2.1/20101210/html4/margin-collapse-164.htm
http://test.csswg.org/suites/css2.1/20101210/html4/margin-collapse-clear-005.htm
http://test.csswg.org/suites/css2.1/20101210/html4/margin-collapse-clear-011.htm

These test cases exhibit a margin collapse behavior that we have discussed many times, however after some extensive review it seems as if the cases themselves are incorrect per the current spec. These cases should be updated to match the latest spec.

Section 9.5.2 states:
Computing the clearance of an element on which 'clear' is set is done by first determining the hypothetical position of the element's top border edge within its parent block. This position is where the actual top border edge would have been if the element had a non-zero bottom border and its 'clear' property had been 'none'.

Using margin-collapse-164 as our example case...

  <style type="text/css">

   .outer { margin: 1em; background: red; height: 4.5em; }

   .border { border: solid; width: 10em; }

   .box { margin: 0; background: yellow; }

   .float { margin: 0; width: 5em; height: 1.5em; background: orange; float: right; }

   .clear { margin-top: 3em; height: 1.5em; background: aqua; clear: both; }

   .control { border: solid; width: 10em; background: yellow; margin: 1em; }

   .control .a { margin: 0 0 0 auto; width: 5em; height: 1.5em; background: orange; }

   .control .b { margin-top: 1.5em; height: 1.5em; background: aqua; }

  </style>

  <div class="outer border">
   <div class="box">
    <div class="float">TEST</div>
    <div class="clear">TEST</div>
   </div>
  </div>
  <div class="control">
   <div class="a">TEST</div>
   <div class="b">TEST</div>
  </div>

Based on section 9.5.2 we first calculate the hypothetical position, within its parent block, of div "clear". We collapse the top margin of "clear" with "box" which puts the "clear" element's top position at 0. We then place the div "float" into the mix. Div "float" element's top position is also at 0 which will trigger the "clear" element to clear since the two intersect.

Since we now clear it will look as if the "clear" element's margin was completely ignored (in reality you end up with negative clearance). Thus the "clear" element will be touching the bottom of the "float" element.

Currently all browsers I have tested in Windows, IE8, IE9, Firefox3.6.13, Firefox 4b8, Opera 11, Safari 5.0.3, Chrome 8.0.552.224, Konquerer 4.4.0 all exhibit the same visual result. This means that we all are in compliance to what the spec states today. However the tests assume a different behavior.

In trying to identify a fix that would match what the tests expected we discovered this issue and an additional one...

Once we had a satisfactory fix for the case we discovered an new issue with the updated behavior resulting in a change to the Acid2 test. Though the behavior within the Acid2 test is partially hidden due to overlapping elements; if the Acid2 test is broken down into individual rows there is an obvious behavior change to the layout of the "smile" section of Acid2.

After all of this analysis, and attempted fix to the solution, it seems as if all the browsers have the correct solution today and there is no need to change the spec further to match what the tests are trying to accomplish. I believe we need to change the tests so elements can have negative clearance (resulting in a visual appearance that the cleared elements move up). This will also mean that implementations do not need to make a change in this area and potentially break sites on the web that may have this situation of float, margin and clear.

--
Thanks,
Arron Eicholz

Received on Tuesday, 28 December 2010 17:08:01 UTC