Re: [CSS21] stack level definitions in 9.9.1

Bert Bos wrote:
> On Saturday 19 June 2010 02:56:44 Sylvain Galineau wrote:
>> Following up on CSS21 issue-60 [1]. Note that while this constitutes
>> my final proposal for the purpose of resolving the issue in CSS2.1
>> this is not in any way meant to suggest the feedback you, Justin and
>> others sent on this topic that is not addressed here was deemed
>> incorrect or irrelevant. It should be addressed in future CSS
>> revisions.
>>
>> The set of proposed changes is somewhat larger than I originally
>> intended but you have convinced me of their coherence. I believe them
>> to be sufficient for this revision of the spec.
>>
>> The proposed edits are as follows; they are meant to be accepted or
>> rejected as a whole:
> 
> Here is my review:
> 
> a) There are some occurrences of "non-positioned floats," which seem to 
> mean simply "floats." (There is no such thing as a positioned float.)

Sure there is.  A positioned float is an element which has 'float' other
than 'none' and 'position' other than 'static'.

 From 9.3.2:[4]

"An element is said to be positioned if its 'position' property has a
value other than 'static'."

What's more, the distinction between positioned floats and
non-positioned floats is important, since positioned elements (floated
or otherwise) lie on one of painting layers 2, 6 and 7 within their
containing stacking context, whereas non-positioned floats lie on
painting layer 4.

Furthermore, this issue is Issue 60a and has already been resolved and
closed.[5]


> b) Layer 6 in edit 3 contains a with-phrase ("with stack level 0") that 
> is ambiguous. The sentence can mean
> 
>     [positioned descendants and stacking contexts] with stack level 0
> or
>     [positioned descendants] and [stacking contexts with stack level 0]
> 
> It means the former, but that requires considerable thinking: one tends 
> to overlook that stack level zero includes elements with 'z-index: 
> auto'.

One shouldn't do; the proposed definition of the 'auto' value of
'z-index' in Edit 1 (which you said was OK) says:

"The stack level of the generated box in the current stacking context is
'0'"


> c) The "descendants" in the list of seven layers are of two types: 
> elements that belong to this stacking context and elements that create 
> child stacking contexts. 

These are not mutually exclusive.  The list of seven painting layers is
describing how the "descendants" (actually "dependants", see below) of
the current stacking context are layered.  Hence they're /all/ elements
that belong to this stacking context.  Of these elements, some
themselves form stacking contexts (thus giving us a stacking context
tree for the document).


> The third kind, descendants that belong to 
> other stacking contexts, are not mentioned.

No, but it's implicit that we're only talking about descendants whose
containing stacking context is the current one.

I'd be the first to lament the woefully incorrect use of "parent",
"child", "descendant" and "ancestor" already present in this section,
and indeed my original proposal[6] made much of this, and suggested
introducing the terms "containing stacking context" and "dependant
elements of a stacking context" to accurately describe the relationships
being described in this section.  It was rejected for CSS21.


> It's easy to omit the 
> word "descendant" in layers 2, 6 and 7 so that all occurrences are of 
> the first type.

I agree there's no harm in dropping "descendant" as it's inaccurate and
doesn't add anything to the understanding.  Bear in mind that these
words are in the existing text, however!  They weren't newly introduced
in the proposal.


> d) I have trouble understanding edit 4 and Anton Prowse's insertion 
> of "and of" doesn't help. Here is how I interpret the sentence:
> 
>     The contents of
>       1) positioned elements with 'z-index: auto',
>       2) non-positioned floats [= floats],
>       3) inline blocks and
>       4) inline tables
>     are stacked as if they [= those four kinds of elements] generated
>     new stacking contexts, except that
>       a) any positioned elements [= their positioned descendants] and
>       b) any elements [= their descendants] that actually create new
>          stacking contexts
>     take part in the parent stacking context [= current stacking
>     context]. 

> The "positioned elements" in the second half aren't the same as 
> the "positioned elements" in the first half.

Agreed.

> The "parent stacking 
> context" is actually the current stacking context.

Well, that's if you're imagining these four types of element in the
wider context of the stacking context to which they belong, yes.  (Which
is the only way that your use of "current" would make sense.)

You don't have to imagine it that way though, and indeed I've never
interpreted that paragraph in that way, myself.  When I read it, I start 
the sentence seeing four types of element being described as isolated 
entities, without reference to the stacking context tree, and when I 
reach "parent stacking context" I interpret it as the "containing 
stacking context" of these elements, ie the closest ancestor stacking 
context of these elements, which throughout this section is described as 
"parent" (cf. my comment below about "child").

> The painting order 
> is defined as that of a stacking context with exceptions, which means 
> you have to look up the normal stacking context and then apply the 
> exceptions.

Indeed.  And, I don't think it matters which of the two ways you
interpret it, the result is the same.

> And the paragraph refers to types of elements that only 
> exist in level 3, viz., non-positioned elements that create a stacking 
> context.

I don't follow you here.  And no non-positioned elements form a stacking 
context in CSS21.

Judging from your amendment below, I think you agree that the phrase
"are stacked as" should be interpreted as "behave as", since the
"stacking" in question in this particular sentence is actually the
painting of the seven layers(*) /within/ these four types of element.
Certainly, I don't see any other way of interpreting that phrase, since
"stacked as if they generated new stacking contexts" is meaningless:
how, for example, is the way stacking contexts are "stacked" different
from the way non-stacking contexts are "stacked"?

(*) Actually, for the four types of element, there are not seven layers 
but four, since the three layers involving positioned elements don't 
"exist" for these four types of element: this is the exception being 
described.

Again, note that the dubious wording is the existing text, not something
newly introduced in the proposal.  The Edit for this paragraph merely
clarifies exactly /which/ elements have "almost stacking context
behaviour".  My original proposal suggested the use of the special term
"pseudo–stacking context" to describe these four types of element and to
clearly distinguish their behaviour from real stacking contexts.  It was
rejected for CSS21.


> Here is attempt to replace the "as if," but I do not suggest using this 
> text, because I may have overlooked some subtlety:
> 
>     Positioned elements with 'z-index: auto' (in layer 6), floats
>     (layer 4), inline blocks (layer 5) and inline tables (layer 5)
>     have sub-layers, as follows:
>     
>        a. the background and borders of the element.
>        b. the in-flow, non-inline-level, non-positioned descendants.
>        c. the floating descendants.
>        d. the in-flow, inline-level, non-positioned descendants,
>           including inline tables and inline blocks.
>     
>     This overrides the painting order above, in the sense that
>     non-positioned descendants of these elements are painted in
>     per-element sub-layers a-d rather than in layers 3-5 of the
>     stacking context they belong to. (Note that positioned descendants
>     are still painted in layer 6.)

Whilst I agree that this is a description of what "as if" means, I don't
think this level of detail is necessary and I don't think it's any
clearer to approach the recursive description of the stacking model in
this "inwards-looking" or "downwards-looking" way.

Furthermore, you're describing two iterations of the recursion 
("stacking contexts have the following painting layers... special 
elements on some of these painting layers, such as floats, behave a bit 
like stacking contexts and they have the following painting layers...") 
which to my mind is not as elegant of describing one iteration of the 
recursion and then explaining how certain painting layers are missing 
for the four special types of elements which behave a bit like stacking 
contexts, as the spec currently does.


> e) Edit 5 talks about the "descendant stacking context with the most 
> negative z-index," where "descendant" actually means "child"

That's as inaccurate as "descendant" (but from the opposite extreme),
unless you're using "child" in the graph-theoretic context of the
stacking context tree, which you may well be doing although it's not
very clear.  Where "descendant" is used throughout 9.9.1, it actually
means "dependant".

Dependants of a stacking context don't need to be direct children, in 
the element-tree sense.  For example, when a positioned element with 
integer z-index contains a float which contains a positioned element 
with integer z-index, the inner positioned element is not painted by the 
float (which does take responsibility for painting /most/ layers exactly 
"as if it generated a new stacking context", but not for painting layers 
for positioned elements).  Instead, the inner positioned element is 
painted by the outer positioned element.

> and also omits 
> that there may be more than one. The original text is better, I think. 
> It is not precise, but at least it is clear that it isn't meant to be.

I wasn't won over by Edit 5 either.  (It was the only one that I was
indifferent about.)


>> 3. In section 9.9.1 [2], replace:
>>        # Each stacking context consists of the following stacking
>>        # levels
>>        # (from back to front):  
>>              # 1.the background and borders of the element forming
>>              #   the stacking context. 
>>              # 2.the stacking contexts of descendants with negative
>>              #   stack levels. 
>>              # 3.a stacking level containing in-flow non-inline-level
>>              #   non-positioned descendants.
>>              # 4.a stacking level for non-positioned floats and their
>>              #   contents.
>>              # 5.a stacking level for in-flow inline-level
>>              #   non-positioned descendants. 
>>              # 6.a stacking level for positioned descendants with
>>              #   'z-index: auto', and any descendant stacking
>>              #   contexts with 'z-index: 0'.
>>              # 7.the stacking contexts of descendants with positive
>>              #   stack levels.
>>        # For a more thorough explanation of the stacking order,
>>        # please see Appendix E.
>>    with
>>        # Within each stacking context, the following layers are
>>        # painted in back-to-front order:
>>              # 1.the background and borders of the element forming
>>              #   the stacking context.
>>              # 2.the stacking contexts of descendants with negative
>>              #   stack levels (most negative first).
>>              # 3.in-flow non-inline-level non-positioned descendants.
>>              # 4.non-positioned floats.
>>              # 5.in-flow inline-level non-positioned descendants,
>>              #   including inline tables and inline blocks.
>>              # 6.positioned descendants and stacking contexts with
>>              #   stack level '0'.
>>              # 7.the stacking contexts of descendants with positive
>>              #   stack levels (least positive first).
>>        # This painting order is applied recursively to each stacking
>>        # context. This description of stacking context painting order
>>        # constitutes an overview of the detailed normative definition
>>        # in Appendix E.
> 
> I suggest:
> 
>     # Within each stacking context, the following layers are painted in
>     # back-to-front order.
>     #
>     #   1. the background and borders of the element forming the
>     #      stacking context.
>     #   2. the child stacking contexts with negative stack levels (most
>     #      negative first).
>     #   3. the in-flow, non-inline-level, non-positioned descendants.
>     #   4. the floating descendants.
>     #   5. the in-flow, inline-level, non-positioned descendants,
>     #      including inline tables and inline blocks.
>     #   6. the stacking contexts with stack level 0, and the positioned
>     #      descendants with 'z-index: auto'.
>     #   7. the child stacking contexts with positive stack levels (least
>     #      positive first).
>     #
>     # This painting order is applied recursively to each stacking
>     # context. This description of stacking context painting order
>     # constitutes an overview of the detailed normative definition in
>     # Appendix E.

I hope you'll reconsider all of your proposed changes, here, as I've
argued above.


>> 4. In section 9.9.1 [2], replace:
>>       # The contents of inline blocks and inline tables are stacked
>>       # as if they generated new stacking contexts, except that any
>>       # positioned elements and any elements that actually create new
>>       # stacking contexts take part in the parent stacking context.
>>       # They are then painted atomically in the inline stacking 
>>       # level. 
>>    with
>>       # The contents of positioned elements with 'z-index: auto',
>>       # non-positioned floats, inline blocks and inline tables are
>>       # stacked as if they generated new stacking contexts, except
>>       # that any positioned elements and any elements that actually
>>       # create new stacking contexts take part in the parent stacking
>>       # context.
> 
> I suggest:
> 
>     # Positioned elements with 'z-index: auto' (in layer 6), floats
>     # (layer 4), inline blocks (layer 5), and inline tables (layer 5),
>     # are painted as if those elements generated new stacking contexts,
>     # except that their positioned descendants and any child stacking
>     # contexts take part in the current stacking context.

My concerns over the use of "child" notwithstanding, I could live with
this "inwards-looking" view of the stacking model instead of the current
"outwards-looking" view... but I do think the floats, inline blocks and
inline tables need to be clearly qualified as "non-positioned".


>> [1] http://wiki.csswg.org/spec/css2.1#issue-60
>> [2] http://www.w3.org/TR/CSS21/visuren.html#z-index
>> [3] http://www.w3.org/TR/CSS21/zindex.html

[4] http://www.w3.org/TR/CSS2/visuren.html#position-props
[5] http://wiki.csswg.org/spec/css2.1#issue-60a
[6] http://dev.moonhenge.net/css21/spec/z-index/

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

Received on Thursday, 8 July 2010 00:38:49 UTC