W3C home > Mailing lists > Public > www-style@w3.org > May 2009

Re: [CSS21] Clearance paradox

From: Anton Prowse <prowse@moonhenge.net>
Date: Sat, 23 May 2009 13:01:37 +0200
Message-ID: <4A17D791.1040603@moonhenge.net>
CC: "www-style@w3.org" <www-style@w3.org>
fantasai wrote:
> Anton Prowse wrote:
>>
>> I think CSS2.1 contains a paradox as regards clearance.
>> ... When H = M2 (which happens to be what the diagram actually shows!) we
>> have a problem:  if clearance is zero then margins collapse and so
>> clearance is non-zero; but if clearance is non-zero then margins don't
>> collapse and the clearance needed is zero.
> 
> Anton Prowse wrote on 2 Apr 2009:
> 
>> The least disruptive solution to the problem discussed therein is to say
>> that an element can still be said to have clearance even if that
>> clearance is zero.  In other words, clearance is a property that
>> elements may possess in addition to being a quantity which is applied.
>> This makes the whole thing hold together conceptually, and required no
>> conceptual changes to the 'clear' property.
> 
> Proposed changes:
> 
> 9.5.2 Controlling flow next to floats: the 'clear' property
> 
> Change
>   # Clearance is introduced as spacing above the margin-top of an element.
>   # It is used to push the element vertically (typically downward), past
>   # the float.
> to
>   | Values other than 'none' introduce clearance as spacing above the
>   | margin-top of an element. Clearance inhibits margin collapsing and
>   | is used to push the element vertically past the float.
> and shift to after value definitions.
> 
> Change
>   # The clearance of the generated box is set to the amount necessary to
>   # place the top border edge below the bottom outer edge of any
> to
>   | Requires that the top border edge of the box be below the bottom
>   | outer edge of any
> x3
> 
> Change
>   # then its clearance must be set to the greater of:
> to
>   | then clearance is introduced and must be set to the greater of:
> 
> Change
>   # The clearance can be negative.
> to
>   | The clearance can be negative or zero.

These changes work for me.

> 
> 8.3.1 Collapsing margins
> 
> Change
>   # An element that has had clearance applied to it never collapses
> to
>   | An element that has clearance never collapses
> 
> Change
>   # When an element's own margins collapse, and that element has had
>   # clearance applied to it
> to
>   | When an element's own margins collapse, and that element has clearance

(Editorial: let's linkify the latter word "clearance")

> 
> Would these changes address the issue?

Yes, with the slight concern that in 8.3.1 (Collapsing margins),[1] the
sentence

   # In this specification, the expression collapsing margins means that
   # adjoining margins (no non-empty content, padding or border areas or
   # clearance separate them) of two or more boxes (which may be next to
   # one another or nested) combine to form a single margin.

is not completely clear about precisely when clearance prevents which
margins from being regarded as "adjoining".  The subsequent prose goes
into more detail about this.  Incidentally, does clearance on a block B
inhibit margin collapsing between B's top margin and the top margin of
its first in-flow child?  The subsequent prose discusses the converse
situation in which it is the /child/ which has clearance.


With this paradox resolved, I have now been able to contemplate 9.5.2
(Controlling flow next to floats: the 'clear' property)[2] and Bert's
email[3] afresh.  As I feared, I can still make no sense whatsoever of
the need, when calculating clearance, to do two calculations:

   # 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 determined
   # after the top margin of the element has been collapsed with previous
   # adjacent margins (including the top margin of the parent block).
   #
   # If this hypothetical position of the element's top border edge is
   # not past the relevant floats, then <del>its</del> clearance <ins>is
   # introduced and</ins> must be set to the greater of:
   #
   #   1. The amount necessary to place the border edge of the block even
   #      with the bottom outer edge of the lowest float that is to be
   #      cleared.
   #   2. The amount necessary to make the sum of the following equal to
   #      the distance to which these margins collapsed when the
   #      hypothetical position was calculated:
   #          * the margins collapsing above the clearance
   #          * the clearance itself
   #          * if the block's own margins collapse together: the block's
   #            top margin
   #          * if the block's own margins do not collapse together: the
   #            margins collapsing below the clearance

The application of clearance occurs only if the hypothetical position of
the element's top border edge is not past the relevant floats, and its
purpose (according to the proposed new definitions of the values 'left',
'right' and 'both') is to require that the top border edge of the box be
below the bottom outer edge of any [left/right/both]-floating boxes that
resulted from elements earlier in the source document.  So surely the
first calculation is the only one necessary?  Under what situation is
the amount necessary to "place the border edge of the block even with
the bottom outer edge of the lowest float that is to be cleared" *not*
the correct amount?

Referring to the example and calculations in Bert's email:

   > we need to compute clearance C twice, C1 and C2, and keep the
   > greater of the two: C = max(C1,C2). The first way is to put the top
   > of B2 flush with the bottom of F

   > The second computation is to keep the top of B2 where it is.

Why would we ever what to do that?  If "where it is" is equal or below
the point of being flush with the bottom of F, then no clearance is
applied, whereas if it is above then according to the definitions of the
values 'left', 'right' and 'both', leaving the top of B2 "where it is"
is not correct behaviour for 'clear'.

Bert mentions that the second calculation is in some way related to what
happens if there are empty blocks whose own margins collapse together
etc, but it remains the case that anything other than the first
calculation (putting the top of B2 flush with the bottom of F)
contradicts the definition of 'clear'.


One final issue: the following sentence in the penultimate list item in
8.3.1 is redundant:

   # An element that has had clearance applied to it never collapses its
   # top margin with its parent block's bottom margin.

because lower down in 8.3.1 it is written that

   # When an element's own margins collapse, and that element has had
   # clearance applied to it, its top margin collapses with the adjoining
   # margins of subsequent siblings but that resulting margin does not
   # collapse with the bottom margin of the parent block.

and this covers a superset of cases. (An element could only collapse its
top margin with its parent block's bottom margin if its own margins
collapsed.)

[1] http://www.w3.org/TR/CSS21/box.html#collapsing-margins
[2] http://www.w3.org/TR/CSS21/visuren.html#flow-control
[3] http://lists.w3.org/Archives/Public/www-style/2009Feb/0108.html

Cheers,
Anton Prowse
http://dev.moonhenge.net
Received on Saturday, 23 May 2009 11:02:44 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:18 GMT