Re: [CSS21] 10.1: Issues with "containing block"

On 22/10/2010 22:13, Peter Moulder wrote:
> On Fri, Oct 22, 2010 at 06:42:39PM +1100, Alan Gresley wrote:
>> On 21/10/2010 19:45, Anton Prowse wrote:
>>> On 21/10/2010 08:06, Alan Gresley wrote:
>>>>
>>>> s/containing block's right edge/containing block's right content edge/
>>>
>>> No, no.  The containing block doesn't have a "content edge"; it's
>>> a rectangular region.
>>
>>
>> If you say this, then you still do not understand what a containing
>> block is. I'm only talking about the change to rule 3 at this
>> moment. The containing block (rectangular region) is formed by the
>> content edge. In 10.1 we have.
>>
>>    | 2. For other elements, if the element's position is 'relative'
>>    | or 'static', the containing block is formed by the content edge
>>    | of the nearest block-level, table cell or inline-block ancestor
>>    | box.
>
> [Preface warning: it's now way past my bedtime, and I haven't re-read what
>   follows; hopefully you can work out what I mean to say if I've mangled
>   something.]
>
> I haven't yet noticed a possible interpretation consistent with the above, but
> on the other hand the text in the current spec does seem a little contradictory
> about what the containing block is.  (I suspect that this is something that has
> changed over time, or something where different spec writers have different
> mental models of what it is.)

Agreed.  It seems pretty clear that the containing block was originally 
conceived as a block box.  This is hinted at by the following 12 
instances in the current ED, although note that the rest of the time the 
spec does use the terminology correctly.  [Further thoughts follow below].

   # 9.1.2 Containing blocks
   #
   # In CSS 2.1, many box positions and sizes are calculated with
   # respect to the edges of a rectangular box called a containing
   # block. In general, generated boxes act as containing blocks for
   # descendant boxes; we say that a box "establishes" the containing
   # block for its descendants.

Note the use of "rectangular box" instead of "rectangle", and the use of 
"act as" instead of omitting that clause and merely linking the phrase 
"establishes the containing block" to 10.1.

   # 9.4.3 Relative positioning
   # [...]
   # If the 'direction' property of the containing block is 'ltr, the
   # value of 'left' wins and 'right' becomes -'left'. If 'direction' of
   # the containing block is 'rtl', 'right' wins and 'left' is ignored.

Note the use of "'direction' property of the containing block" instead 
of "'direction' property of the element establishing the containing 
block" (the elements vs boxes saga notwithstanding)

   # 9.8.4 Absolute positioning
   #[...]
   # The following example shows an absolutely positioned box that is a
   # child of a relatively positioned box. Although the parent outer box
   # is not actually offset, setting its 'position' property to
   # 'relative' means that its box may serve as the containing block for
   # positioned descendants.

Note the use of "serve as" instead of "establish".

   # 9.10 Text direction: the 'direction' and 'unicode-bidi' properties
   # [...]
   # User agents that support bidirectional text [...]. The paragraph
   # embedding level is set according to the value of the 'direction'
   # property of the containing block rather than by the heuristic given
   # in steps P2 and P3 of the Unicode algorithm.

Note the use of "'direction' property of the containing block" instead 
of "'direction' property of the element establishing the containing block".

   # 10.1 Definition of "containing block"
   # [...]
   # (final example)
   # If we position "div1":
   #     #div1 { position: absolute; left: 50px; top: 50px }
   # its containing block is no longer "body";[...]
   # [...]
   # By positioning "em1", its containing block becomes the nearest
   # positioned ancestor box (i.e., that generated by "div1").

Note the use of "containing block is no longer "body"" instead of 
"containing block is no longer established by "body""; and the use of 
"its containing block becomes the nearest positioned ancestor box" 
instead of "its containing block is established by the nearest 
positioned ancestor box".

   # 10.3.3 Block-level, non-replaced elements in normal flow
   # [...]
   # If all of the above have a computed value other than 'auto', the
   # values are said to be "over-constrained" and one of the used values
   # will have to be different from its computed value. If the
   # 'direction' property of the containing block has the value 'ltr',
   # [...]

Note the use of "'direction' property of the containing block" instead 
of "'direction' property of the element establishing the containing block".

   # 10.3.7 Absolutely positioned, non-replaced elements
   # [...]
   # If none of the three is 'auto': If both 'margin-left' and 'margin-
   # right' are 'auto', solve the equation under the extra constraint
   # that the two margins get equal values, unless this would make them
   # negative, in which case when direction of the containing block is
   # 'ltr' ('rtl'), [...]. If the values are over-constrained, ignore
   # the value for 'left' (in case the 'direction' property of the
   # containing block is 'rtl')

Note the use of "direction of the containing block" and of "'direction' 
property of the containing block" instead of "'direction' property of 
the element establishing the containing block".  (Compare this with the 
preceding paragraph where the phrasing is correct.)

   # 10.3.8 Absolutely positioned, replaced elements
   # [...]
   # 4. If at this point both 'margin-left' and 'margin-right' are still
   # 'auto', [...], in which case when the direction of the containing
   # block is 'ltr' ('rtl'), [...].
   # 5. [...]
   # 6. If at this point the values are over-constrained, ignore the
   # value for either 'left' (in case the 'direction' property of the
   # containing block is 'rtl') [...]

Note the use of "direction of the containing block" and of "'direction' 
property of the containing block" instead of "'direction' property of 
the element establishing the containing block".



> My own understanding is that what we want the containing block to be is
> a tuple of:
>
>    - a rectangle (axis-aligned, and whose width may be negative); and
>
>    - a 'direction' value (i.e. either 'ltr' or 'rtl').
>      (In particular, it is just a single value, there is no distinct specified value,
>      computed value etc.)

Probably, but at this stage I think that the best we can hope for is to 
refer to the 'direction' property of the element/box establishing the 
containing block, rather than redefining containing block itself.  I 
share your (unquoted) thoughts about the difficulty of attaching 
'direction' to the initial containing block, which is unique in not 
being "established by" any element.  Currently the spec propagates the 
value specified on the root element (meaning that this value is used for 
both the initial containing block and for the containing block which the 
root element establishes), and I think it's OK to preserve that.


> I should also note that my understanding is that the containing block is to be
> a property of boxes, not of elements, and that the containing block is defined
> in terms of box tree parents rather than element tree parents.

Very possibly.  But this is an orthogonal issue.  (The usual questions 
arise: what's the containing block of a run-in that runs in, etc.)


> There is just one other change that we should at least consider, and that is to
> rename the term "containing block" so as not to give the impression that it's a
> block, and so as to avoid confusion with "block container", which is similar
> enough that the two might be taken to be synonyms.  Of course "containing
> block" is a well-established phrase, which does make this a questionable change.
> We could somewhat mitigate this by adding that "previous versions of this
> specification called this ...".

> If we were to rename "containing block", then a candidate new name would be
> "basis rectangle".

I too think that "containing block" is less than ideal.  Sounds like a 
big change at this stage in the game, though.

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

Received on Monday, 25 October 2010 16:46:30 UTC