Re: [CSS21] Trivial editorial issues with 9.5 (Floats)

> On 05/08/2010 18:24, fantasai wrote:
>> On 10/05/2009 09:34 AM, Anton Prowse wrote:
>>> Some trivial editorial issues with 9.5 (Floats):

>>> Issue 1:
>>>
>>> # Since a float is not in the flow, non-positioned block boxes created
>>> # before and after the float box flow vertically as if the float did
>>> # not exist.
>>>
>>> s/non-positioned/in-flow/
>>> (Relatively positioned boxes are not usually removed from the flow.)
>>
>> Good catch. But should it be "in-flow" or "non-floating"?

"in-flow".  If they're out of flow then they're not up for consideration
in that sentence, which is specifically talking about flow.


We can consolidate and clarify the rest of the issues from this thread
as follows.

9.5 explains the concept of line box shortening, but defers to the rules
in 9.5.1 for where to place the float.  9.5 needs to cover the following
facts:

(i) It is prohibited for line boxes next to floats to overflow their
containing block.  That is, if flowing inline-level boxes into a line
box next to a float would result in overflow, after taking all available
break points, then the line box is moved down to beneath the float.

(This fact is interesting; if there's a tall, zero-width float at the
left of a box, the box's line boxes behave differently than they would
if the float didn't exist, even though the line boxes have the same
width "available".  Obvious, I suppose, and irrelevant to the issues at
hand; but it hasn't crossed my mind until now.)


(ii) In the case of floats which would be inline-level if they weren't
floated, inline-level content preceding the float in the document tree
may need to be reflowed after placing the float appropriately.

This fact motivates an important design decision.  It's necessary that
the relationship between the position of the float and the position of
its "placeholder" be constructed carefully to avoid circularity.

In a post on a different thread,[1] I described the three obvious
possibilities for that relationship:

1.) Always move the float downwards to the bottom of the line box in
which its placeholder sits, when no non-empty inline-level box precedes
the placeholder on that line box.  (Prior inline-level content is never
reflowed, and the float is always below all prior content.)

2.) Once its width as a float has been computed (which is independent of
its position on the page), move the float downwards only if there is
prior inline content in the line box in which its placeholder sits and
this computed width exceeds the remaining space in that line box.  (Keep
the float on the same line as its placeholder provided that doing so
wouldn't cause the prior content to be reflowed into more line boxes
than have already been generated; if it would, then the float is put
below its placeholder and no reflow is needed at all.)

3.) Once its width as a float has been computed, move the float
downwards only if the line box in which its placeholder sits is already
a shortened line box and if this computed width exceeds the width of the
line box, irrespective of whether there is prior inline content
in the line box. (Keep the float on the same line if at all possible.
Prior content may need to be reflowed into one more new line boxes, and
the float may be above – but never below – its placeholder.)

The current spec seems to opt for (2), and this is what is implemented
in most newer browsers.  (Some older browsers did (1).)

(3) is the dangerous one; it could cause circularity unless we view the
"timing" editorial device – that the spec describes sequential layout
rather than final state – as normative.


The discussion on this thread has centered around these two facts.

Firstly, 9.5 tries to describe (i) but goes off-track, inappropriately
concerning itself with situations relevant to fact (ii):

On 05/08/2010 19:21, L. David Baron wrote:
> On 05/08/2010 18:24, fantasai wrote:
>> On 10/05/2009 09:34 AM, Anton Prowse wrote:
>>> Issue 2:
>>>
>>> # However, line boxes created next to the float are shortened to make
>>> # room for the margin box of the float. If a shortened line box is too
>>> # small to contain any further content, then it is shifted downward
>>> # until either it fits or there are no more floats present.
>>>
>>> Delete "further"
>>> (No prior content is referred to.)
>> Prior content would be content before the float.
> 
> I think in this case deleting "further" is an improvement.  This
> isn't really about content before/after the float.

Exactly.  It's about short line boxes in general.  Furthermore, we need
s/it fits/content fits/
since fact (i) isn't about line boxes fitting next to floats, it's about
content fitting into line boxes whilst avoiding overflow.


Secondly, 9.5 tries to set out fact (ii), but makes a mess of how it
describes which of the three relationships I've described above is
dictated to us by the rules in 9.5.1 (to which it defers):

> (You might be confusing this with the rule that one can derive from
> the interaction of rules 6 and 8 in the float placement rules in
> http://www.w3.org/TR/CSS21/visuren.html#float-rules which says that
> if the line box shortening caused by placing the float next to the
> line that it would be on if it were instead an empty inline (i.e.,
> the line that its "placeholder" is on) would cause the line to break
> at a point prior to that placeholder, then the float gets pushed to
> below that line box according to rule (8) because the position next
> to the line box is no longer "possible" according to rule (6).  But
> that isn't about whether content is before or after the float; it's
> about whether content is before or after the first breaking
> opportunity following the float.)

Rule 6 basically rules out Relationship 3.  Rules 6 and 8 together rule
out Relationship 1.  The rules in 9.5.1 don't spell out for us that
Relationship 2 is the only possibility remaining, so it's back to 9.5,
and Issue 3:

>>> Issue 3:
>>>
>>> # Any content in the current line before a floated box is reflowed in
>>> # the first available line on the other side of the float.
>>>
>>> When is the first available line anything other than the current line?
>>> If never, then s/first available/same/
>> If the line is forced to break, then some of the content will not be
>> placed in the current line.
> 
> No, that can't happen if the content isn't before the float.

I don't understand the second half of David's sentence, but I agree that
it can't happen.  (fantasai's thinking of Relationship 3, which is
already ruled out by 9.5.1.)  As explained for Relationship 2, and
demonstrated with examples in my earlier posts on this thread,[3,4] the
prior content always remains on the same line, possibly "moved" to the
other side of the float.  (Which, apart from being typographically
pleasing, is also pleasing for implementors I imagine.)

Thus Issue 3 still stands, but it's a headache to fix using informal
language whilst still achieving an accurate wording.  One particular
thing which I'm struggling with – monospaced font required – is that in
the case of

|         |
|text FLOAT

where FLOAT is a floated span, then FLOAT doesn't "fit" when considered
as a span, but actually does fit when considered as a float because the
space between text and FLOAT gets discarded: the correct rendering is

|FLOATtext|

not

|text     |
|FLOAT    |

I think there'll be reluctance to talk about placeholders in 9.5, but I
think we might not have any choice.

Once the problem sentence in Issue 3 is fixed, I think we also need to
turn the following normative text into an actual example (which might
also be sufficient to address the fourth issue, see below):

   # In other
   # words, if inline boxes are placed on the line before a left float is
   # encountered that fits in the remaining line box space, the left
   # float is placed on that line, aligned with the top of the line box,
   # and then the inline boxes already on the line are moved accordingly
   # to the right of the float (the right being the other side of the
   # left float) and vice versa for rtl and right floats.

> (This sentence also is rather unclear.  It took me about two minutes
> of reading the context, particularly the sentences following, to
> understand that it meant that if you have a left float when some
> content is already on the line, it pushes that content to the right.
> Describing that as "the other side of the float" seems quite
> confusing to me.)

Indeed.  And ุyvind Stenhaug raised an important point earlier in this
thread concerning left floats in right-to-left flow.[4]  The latter, at
least, definitely needs addressing.


[1] http://lists.w3.org/Archives/Public/www-style/2009Oct/0289.html
[2] http://lists.w3.org/Archives/Public/www-style/2009Oct/0055.html
[3] http://lists.w3.org/Archives/Public/www-style/2009Oct/0057.html
[4] http://lists.w3.org/Archives/Public/www-style/2009Oct/0058.html

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

Received on Wednesday, 11 August 2010 15:34:37 UTC