CSS Block Model Additions: Floats and Flows

Perhaps if I start from the other direction, discussing floating and  
flowing, my proposal will be clearer.

After all the complicated rules are decoded, applying the style  
‘float: left;’ (or ‘right’) to a block does four things. (The rules  
for items 1 - 3 are in CSS 2.1, Section 9.5. The rules for item 4 are  
in CSS 2.1, Section 9.9.1.)

   1.  Makes the ‘floated’ element a ‘block’ if it is not already a  

   2.  Moves the ‘floated’ (block) element as far left (right) in the  
enclosing block as possible, accounting for prior ‘floated’ elements,  
adjusting down only when there is not enough remaining horizontal  
space to fit the newly ‘floated’ element.

   3.  Shortens and moves the line boxes right (left) and reflows/ 
flows the contents of those boxes so they no longer are ‘behind’ the  
floated element(s). Once the line boxes pass the bottom edge of the  
‘floated’ element(s), they resume their usual sizes and shapes.

   4.  Permits blocks which overlap the floated element(s) to have  
their backgrounds behind the floated element and their contents  
(inflow, inline-level descendants) in front of the floated element 
(s). (See stacking context level rules 3, 4, and 5.) (Overlapped  
blocks are earlier in the document, overlapping blocks are later.)

Because this condition, where one CSS property has multiple effects,  
may tempt designers to try and use some of these effects to produce  
layouts, but for purposes for which they were not intended, I would  
like to allow designers to use these four abilities separately.

This is less effort than it might at first seem, because:

Item 1 can be done using ‘display: block:’ (or ‘display: table;’ for  
an inline-table element).

Once the element is a block type, it may be positioned using  
‘position: absolute;’ to more or less match the effect of item 2,  
above. Other placements are possible using ‘static’, ‘relative’, and  
‘fixed’ positions. Or a new property, ‘block-float’ could duplicate  
all the complications, including the horizontal and vertical  
adjustments when other floated blocks are present, but without  
changing the line boxes, reflowing their contents, and overlapping  
other blocks.

The behavior described in item 4  (background behind, contents in  
front of the float) is (more or less) the default. If a designer  
wants the ‘floated’ element completely behind or in front of the  
overlapping block, he/she can use the ‘z-index’ property to place it.  
The described behavior is not possible to duplicate if the overlapped  
block is not a descendant of the block enclosing the floated element,  
but a new CSS property might be defined to allow this behavior. For  
instance: allow the ‘z-index’ style to control the back/front  
behavior and make ‘overlap’ either ‘split’ or ‘none’, when the two  
elements have the same z-index. (The default z-index is ‘0’.)

Finally, a new property, tentatively named ‘flow-around’ could allow  
designer control of the flow/reflow behavior. If a block (presumably  
a ‘floated’ one) overlaps another, the ‘flow-around’ property of the  
overlapping block could cause the line boxes of the overlapped block 
(s) to be repositioned so they are not obscured by the overlapping  
block. This would be slightly more complex than the current ‘float:  
left;’ and ‘float: right;’ because the overlapping block might be in  
the middle, to one side, or even all the way across the block being  
reflowed. Also, at some point, the existence of other languages,  
which do not necessarily flow left-to-right or right-to-left, will be  
recognized and floats may need to be positioned ‘top’ or ‘bottom’.

So: a new property, ‘flow-around’ is proposed.

Possible values are: ‘none’, ‘before’, ‘after’, and ‘both’.

If a block with ‘flow-around’ set overlaps a block with (some kind  
of) text or other inline elements, the following happens:

‘flow-around: none;’    The line boxes are not resized and the inline  
elements are NOT reflowed in the overlapped block. Use the ‘z-index’  
and ‘overlap’ properties to determine how it will be displayed. CSS  
already has rules for this case, except the possibility of the  
‘overlap’ property.

‘flow-around: before;’  The line boxes of the overlapped block are  
resized to fit in the space before the overlapping block. (Before  
depends on the text flow direction: ltr, rtl, ttb, etc.). Then the  
inline elements are reflowed/flowed to fit in the line boxes. (For  
English, this would be the same as ‘float: right;’ where a block is  
right-shifted and the text is flowed to the left around it.)

‘flow-around: after;’     The line boxes are resized to fit in the  
space after the overlapping block. Then the inline elements are  
reflowed/flowed to fit in the line boxes.

‘flow-around: both;’     The line boxes are split and resized to fit  
in the spaces before and after the overlapping block (presuming there  
is space on both sides). Then the inline elements are reflowed/flowed  
to fit, with as many elements on either side of the split as possible  
and the ‘floated’ element equivalent to a (large) space between words.

The default should be ‘both’ just as in a regular ‘float’ condition.  
A non-floating overlap would be ‘none’.

If there are multiple blocks floated, their ‘flow-around’ properties  
interact, so some may have text on only one side, and some on both  
sides of the ‘floated’ elements. For example, when two blocks are  
floated left, with the second (later, further right) one taller than  
the first one, the text could be only on the right where the two are  
next to each other (assuming the first on is against the left  
margin), but might be on both the left and the right where the second  
one projects below the first and is not adjacent to the left margin.  
This is not possible with the current ‘float’ property. (It might not  
be the desired behavior, but that is controllable by the designer.)

James Elmore

Received on Friday, 27 July 2007 23:03:01 UTC