W3C home > Mailing lists > Public > www-style@w3.org > March 2011

Re: [CSS2.1-9.5] [CSS2.1-9.4.1] Block formatting context and Floats

From: Sylvain Galineau <sylvaing@microsoft.com>
Date: Fri, 11 Mar 2011 18:42:09 +0000
To: "Anton Prowse (prowse@moonhenge.net)" <prowse@moonhenge.net>
CC: "www-style@w3.org" <www-style@w3.org>
Message-ID: <045A765940533D4CA4933A4A7E32597E2AB8CABB@TK5EX14MBXC113.redmond.corp.microsoft.com>
Anton,

The CSSWG has resolved to edit the CSS2.1 specification [1] to reflect your feedback.
In particular, in 9.5 Floats:

# The border box of a table, a block-level replaced element, or an element in the 
# normal flow that establishes a new block formatting context (such as an element 
# with 'overflow' other than 'visible') must not overlap any floats in the same 
# block formatting context as the element itself.

...will be updated like so (changed section between []):

# The border box of a table, a block-level replaced element, or an element in the 
# normal flow that establishes a new block formatting context (such as an element 
# with 'overflow' other than 'visible') [must not overlap the margin box of any 
# floats] in the same  block formatting context as the element itself.


Please respond before 14 March, 2011 if you do not accept the current resolution.

[1] http://w3.org/TR/CSS

Original messages: http://lists.w3.org/Archives/Public/www-style/2009Jan/0352.html
http://lists.w3.org/Archives/Public/www-style/2009Mar/0279.html
ISSUE-278: http://wiki.csswg.org/spec/css2.1#issue-278

From: Anton Prowse <prowse@moonhenge.net> 
Date: Wed, 21 Jan 2009 22:14:30 +0100
 Message-ID: <49779036.1040909@moonhenge.net> 
CC: www-style@w3.org 


fantasai wrote:
> Anton Prowse wrote:
>> 9.5 (Floats) states that the border box of an in-flow block formatting 
>> context B must not overlap(*) any float F in the same block formatting 
>> context P as the element itself, but does not refer to the margin box 
>> of B.  [Other floats, being out of flow, are excluded from this 
>> requirement; this is in keeping with the following sentence higher up 
>> in 9.5 which does explicitly refer to the margin box: "a floated box 
>> is shifted to the left or right until its outer edge touches the 
>> containing block edge or the outer edge of another float".]
>>
>> On the other hand, 9.4.1 (Block formatting contexts) states that a box 
>> B's
>> left outer edge touches the left edge of the containing block P, even in
>> the presence of the float F, unless B establishes a new block formatting
>> context (in which case B may become narrower due to the presence of F).
>>
>> Then, irrespective of whether or not B becomes narrower, if the UA 
>> decides
>> that B can sit next to F and if the left margin of B is less than the sum
>>     s = (left margin of F) + (border area width of F) + m
>> then B must be shifted rightwards away from the left edge of the 
>> containing
>> block P.  The issue is that it is not clear by how much. 
> 
> The "unless" excludes BFCs from needing to connect their outer edges with
> edges of the containing block. As for by how much, it would have to be at
> least enough to prevent overlap, but the spec explicitly leaves the 
> narrowing
> effect undefined, so the position of its edge is therefore also undefined.
> 
> So, am I understanding correctly that you want that position (and therefore
> exactly how much the block gets narrowed) to be defined?

Well, either it should be defined or IMO the spec should be more 
explicit in how it is undefined.  There are four sensible options:

B's left margin edge touches F's right margin edge;
B's left border edge touches F's right margin edge;
B's left margin edge touches F's right border edge;
B's left border edge touches F's right border edge;

Of these, only the first two occur in the major browsers, judging from 
the rendering of a simple test case[1], and we see that even the very 
latest versions of these browsers do not agree on the behaviour:

B's left margin edge touches F's right margin edge: Fx1.5.0.12/win; 
Op9.62/win; IE8PB1;
B's left border edge touches F's right margin edge: Fx3.0.5/win; 
Fx3.2b2/win; Op8.54/win; Op9.27/win; Sf3.2.1/win; IE6; IE7;

That only the first two options are implemented makes reasonable sense, 
since a float's margin is "solid" everywhere else in the spec and so one 
would not expect it to be ignored here.

I would prefer the behaviour to be defined, although I am indifferent as 
to which is chosen, and I confess to not being aware of /any/ examples 
in the wild where a non-floated BFC sits next to a float(*) and where 
the author is relying on a particular rendering result, as alluded to by 
Boris Zbarsky[2], so I can't fully evaluate why a particular one might 
be preferable.  (Not that I doubt him.)

(*) Note that adjacency of two floats is a different matter, is 
explicitly defined (as being the first option), and is a common and 
reliable method of achieving grid-like "multi-column" layouts.

However, if it is to remain undefined I think it should be explicitly 
stated that the first two options are the only acceptable possibilities.

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

[1] 
http://dev.moonhenge.net/css21/test-cases/block-formatting-contexts/block-formatting-contexts-next-to-floats.html
[2] http://lists.w3.org/Archives/Public/www-style/2008May/0226.html

From: Anton Prowse <prowse@moonhenge.net> 
Date: Sun, 22 Mar 2009 16:32:05 +0100
 Message-ID: <49C659F5.3040004@moonhenge.net> 
To: www-style@w3.org 

Anton Prowse wrote:
> Bert Bos wrote:
>> On Wednesday 21 January 2009, Anton Prowse wrote:
>>> fantasai wrote:
>>>> Anton Prowse wrote:
>>>>> 9.5 (Floats) states that the border box of an in-flow block
>>>>> formatting context B must not overlap(*) any float F in the same
>>>>> block formatting context P as the element itself, but does not
>>>>> refer to the margin box of B.  [Other floats, being out of flow,
>>>>> are excluded from this requirement; this is in keeping with the
>>>>> following sentence higher up in 9.5 which does explicitly refer to
>>>>> the margin box: "a floated box is shifted to the left or right
>>>>> until its outer edge touches the containing block edge or the
>>>>> outer edge of another float".]
>>>>>
>>>>> On the other hand, 9.4.1 (Block formatting contexts) states that a
>>>>> box B's
>>>>> left outer edge touches the left edge of the containing block P,
>>>>> even in the presence of the float F, unless B establishes a new
>>>>> block formatting context (in which case B may become narrower due
>>>>> to the presence of F).
>>>>>
>>>>> Then, irrespective of whether or not B becomes narrower, if the UA
>>>>> decides
>>>>> that B can sit next to F and if the left margin of B is less than
>>>>> the sum s = (left margin of F) + (border area width of F) + m then
>>>>> B must be shifted rightwards away from the left edge of the
>>>>> containing
>>>>> block P.  The issue is that it is not clear by how much.
>>>> The "unless" excludes BFCs from needing to connect their outer
>>>> edges with edges of the containing block. As for by how much, it
>>>> would have to be at least enough to prevent overlap, but the spec
>>>> explicitly leaves the narrowing
>>>> effect undefined, so the position of its edge is therefore also
>>>> undefined.
>>>>
>>>> So, am I understanding correctly that you want that position (and
>>>> therefore exactly how much the block gets narrowed) to be defined?
>>> Well, either it should be defined or IMO the spec should be more
>>> explicit in how it is undefined.  There are four sensible options:
>>>
>>> B's left margin edge touches F's right margin edge;
>>> B's left border edge touches F's right margin edge;
>>> B's left margin edge touches F's right border edge;
>>> B's left border edge touches F's right border edge;
>>
>> We have no idea yet by how much a block may become narrower.
> 
> Sure.
> 
>> Maybe it is possible to define an automatic rule that takes the 
>> "intrinsic minimum size" (a term that is going to be defined in level 
>> 3) into account, or maybe we'll need a new property that lets the 
>> designer decide if and by how much a block can become narrower.
> 
> Interesting.
> 
> However, the more I think about this, the more I think that there are 
> two unrelated but similar issues here.  On the one hand, there's  "is it 
> possible to make this block narrower? How much narrower can it feasibly 
> be?".  On the other hand, there's the issue of whether, given a block 
> which can be narrowed and whose minimum feasible width is less than or 
> equal to the "space next to the float", the margin edge of the block 
> should slide under the margin edge of the float or abut it.  Obviously, 
> the available "space next to the float" depends on the answer to the 
> latter question.  It's the latter issue rather than the former which I 
> was raising, and superficially it seems possible to "solve" the latter 
> issue in CSS21 while leaving the former to CSS3.
> 
> Note that all the major desktop browsers will narrow CSS21 BFCs in 
> general, not just tables (the original use-case).  As I noted before, 
> the browsers are divided as follows:
> 
> B's left margin edge touches F's right margin edge: Fx1.5.0.12/win; 
> Op9.62/win; Op10a/win; IE8PB1;
> 
> B's left border edge touches F's right margin edge: Fx3.0.5/win; 
> Fx3.2b2/win; Op8.54/win; Op9.27/win; Sf3.2.1/win; IE6; IE7;
> 
> Even if this issue is intentionally left unspecified in CSS21, authors 
> still want cross-browser compatibility.  Before lobbying one group or 
> the other (and with the window for changes very nearly closed on IE8), I 
> guess I'm just looking for input from implementors and other interested 
> parties as to whether they have a strong preference one way or the other 
> on the two possibilities.  It's interesting that Opera changed sides 
> unilaterally for the 9.62 release, after Firefox had already changed 
> sides in the other direction!

Firstly, I just wanted to note for the record that the recent public RTW
release of IE8 has the latter of the two behaviours described above,
as does Sf4b/win.[1]

Thus IE8 sticks with IE6/7's "BFC's margin slides under F's margin"
behaviour (shared by Firefox and Safari) and turns its back on the
"BFC's margin abuts F's margin" behaviour used in the earlier pre-final
releases (shared by the latest versions of Opera).

We see that browser consensus is moving towards the "slide under if
necessary" behaviour and away from the "margins abut if necessary"
behaviour that is the behaviour of adjacent floats.

This situation seems reasonable to me, since it maximizes the available
space (which fits with the historical reason for squeezing BCFs next to
floats), albeit at the expense of "ignoring" the BFC's own margin (of
which, more to follow).

Note that in every browser tested so far, if the BFC has a positive left
margin large enough so that if it were to start at the left content edge
of its containing block then its left border edge would lie strictly to
the right of the float's margin area, then that /is/ where it starts and
we can say that the float has no influence over the placement of the
BFC.[2]  This behaviour is also reasonable.


Secondly, I wanted to expand a little on those two behaviours described
above, which assumed that the margins in question were non-negative.

When the float has a negative right margin and the BFC has a
non-negative right margin, the same two behaviours are seen in all
browsers tested.[2]  As before, the float has no influence over the
placement of the BFC if the BFC's left margin is non-negative and large
enough.

When the BFC has a negative left margin, there are still more or less
two schools of thought, but this time Safari jumps into the Opera camp
instead of behaving like IE and Firefox.

In the IE and Firefox camps, the BFC's negative left margin is
"ignored".  However, when the float has a negative right margin, in
IE<=7 and Firefox the BFC's left margin edge is not permitted to be
further left than the left content edge of its containing block, whereas
in IE8 the BFC's left /border/ edge is not permitted to be further left
than the left content edge of its containing block.

In the Safari and Opera camps, the BFC's negative left margin is not
"ignored" and its left edge is incident with the float's right margin
edge.  Neither browser places further constraints.


                        Fx3.x/IE6/IE7    IE8    Sf3/Sf4    Op9.6/Op10
positive BFC margin          s           s        s            a
pos BFC CB constraints       m           m        m            m
negative BFC margin          i           i        n            n
neg BFC CB constraints       m           b        -            -

Legend:
   s = "slide under"
   a = "abut"
  CB = containing block
   i = "ignored" (subject to CB constraints)
   n = not "ignored" (subject to CB constraints)
   m = BFC margin box cannot leave
   b = BFC border box cannot leave
   - = no constraints.

In all cases, the transitions are continuous when the margins of the
float and the BFC are varied, which is nice.  However, of the four
different behaviours exhibited, IE8's and Opera's seem the most
user-friendly because, for a given right margin on the float, the
horizontal coordinate of the BFC's border box strictly increases as its
left margin increases (subject, in IE8, to the former having a lower
bound).  This prevents confusion for authors arising from changes to the
BFC's left margin seeming to have an effect at some times and not at others.

The above, taken together with the preference for sliding, means that
the IE8 behaviour is the most desirable.


[1]
https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=399822
[2] 
http://dev.moonhenge.net/css21/test-cases/block-formatting-contexts/block-formatting-contexts-next-to-floats.html

Cheers,
Anton Prowse
http://dev.moonhenge.net
Received on Friday, 11 March 2011 18:42:45 GMT

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