[CSS21] A bluffer's guide to Issue 203 (clearance and hypothetical border position)

In order to understand Issue 203, it's helpful to review in simple terms 
what the clearance concept is designed to do.  (See, for example, 
"Clearance - the missing manual" [1].)

Clearance is introduced when a clearing element is not "naturally" 
sufficiently low down the page to come below relevant floats. 
Specifically, the top border edge of the clearing element is tentatively 
determined under the assumption of "clear:none".  If this tentative 
position is not below (or incident with) the bottom margin edge of the 
relevant floats then clearance is introduced.


Ever since 2003 when the clearance concept was adopted, the wording of 
the spec has been rather vague about what the tentative top border edge 
position is.  In the latest 2010 WD, a change was made (as a result of 
Issue 158 and a subsequent early attempt[2] at addressing the 
then-unfiled Issue 203) to clarify the vagueness.  However, instead of 
changing the spec to explicitly use the actual top border position under 
"clear:none" as the tentative position, it changed the spec to use a 
"hypothetical position" which is the same as the actual top border 
position in many cases but differs in certain cases when the clearing 
element is self-collapsing.

(One important point to grasp here is that the top border position of a 
self-collapsing element is well-defined in 8.3.1; there's no ambiguity 
or mystery about any element's position in its enclosing block 
formatting context.)

Issue 203 argues that it makes no sense to use anything other than the 
actual top border position as the tentative position, irrespective of 
what the original spec intended prior to the 2010 change (which has 
never actually been established!).

Here is the all-important test case:

<div style="float:left; width:100px; height:100px; background:green"></div>
<div style="height:20px; background:gray"></div>
<div>
     <div style="clear:left; margin-bottom: 100px">
         <div style="float:left; width:100px; height:100px; 
background:yellow"></div>
     </div>
</div>

(The floated child is present merely to indicate the top border position 
of its self-collapsing parent.  An absolutely-positioned child could 
have been used instead, but there are possible browser bugs concerning 
the containing block and static position of absolutely-positioned 
elements that are best avoided so as not to muddy the waters.)

In the rendering I desire, the top of the yellow indicator float would 
be 20px below the bottom of the green initial float.  According to the 
current WD, the yellow indicator float will in fact be flush with the 
bottom of the green initial float.  (See below for the calculations.)

The following browsers show what I desire:

IE 8+
Fx 3+

The following browsers show the yellow float flush with the bottom of 
the green float:

Op 9.2+
Sf 5

Hence there is no interop on this issue, and we have the luxury of being 
able to choose the most sensible rendering.

Let's work through the calculations for the test case.  Let us first 
pretend that the clearing element C has "clear:none".  C is 
self-collapsing, and according to 8.3.1.6.1 its top border position is 
the same as that of its parent P (with which it collapses its margins), 
which, according to 8.3.1.6.2, is where it would be if P had a non-zero 
bottom border, ie 100px below the bottom of the gray div, or 
equivalently 20px below the bottom of the initial float.  (The indicator 
float inside of C thus starts 20px below the bottom of the initial float.)

Under my proposed resolution, our tentative reference position of the 
clearing element is precisely the position just calculated.  Since it is 
already below the bottom of the float, no clearance is introduced.  The 
indicator float remains at 20px below the initial float, exactly where 
it would be if the clearing element had "clear:none".

However, under the current WD, the tentative reference position of the 
clearing element C is different.  It is defined to be where the top 
border position C would be /if C had a non-zero bottom border/, namely 
flush with the bottom of the gray div, or equivalently only 20px below 
the top of the initial float.  Thus, clearance is introduced and C is 
moved (upwards!) so that its actual top border position (marked by the 
top of the indicator float) is flush with the bottom of the initial float.

I claim that we should make the tentative top border position be the 
actual top border position under the assumption of "clear:none".  This 
is the only typographically sensible resolution; after all, why would we 
want to introduce clearance when the clearing element is already 
"naturally" below the bottom of the float?

Further nitty-gritty details of this issue can be found in [3].  A 
normalized version of the test case (showing red when a UA fails to 
honour the 2011 WD) can be found in [4,5].


[1] http://lists.w3.org/Archives/Public/www-style/2010Aug/0261.html
[2] http://lists.w3.org/Archives/Public/www-style/2010Aug/0460.html
[3] http://lists.w3.org/Archives/Public/www-style/2010Aug/0526.html
[4] 
http://dev.moonhenge.net/css21/test-cases/clearance/CSS21_Issue203_WD2010.html
[5] http://lists.w3.org/Archives/Public/www-archive/2011Mar/0036.html

Cheers,
Anton Prowse
http://dev.moonhenge.net

Received on Thursday, 24 March 2011 20:32:31 UTC