W3C home > Mailing lists > Public > www-style@w3.org > July 2012

Re: [css3-flexbox] Painting order

From: Anton Prowse <prowse@moonhenge.net>
Date: Fri, 20 Jul 2012 17:44:21 +0200
Message-ID: <50097CD5.20202@moonhenge.net>
To: "www-style@w3.org" <www-style@w3.org>
CC: Morten Stenshorne <mstensho@opera.com>, "Tab Atkins Jr." <jackalmage@gmail.com>
On 20/07/2012 17:20, Morten Stenshorne wrote:
> Anton Prowse <prowse@moonhenge.net> writes:
>
>> On 20/07/2012 16:37, Morten Stenshorne wrote:
>>> Anton Prowse <prowse@moonhenge.net> writes:
>>>
>>>> On 20/07/2012 13:22, Morten Stenshorne wrote:
>>>>> Anton Prowse <prowse@moonhenge.net> writes:
>>>>>
>>>>>> On 20/07/2012 12:48, Morten Stenshorne wrote:
>>>>>>> Anton Prowse <prowse@moonhenge.net> writes:
>>>>>>>
>>>>>>>> On 20/07/2012 11:14, Morten Stenshorne wrote:
>>>>>>>>> Anton Prowse <prowse@moonhenge.net> writes:
>>>>>>>>>
>>>>>>>>>> On 20/07/2012 09:35, Morten Stenshorne wrote:
>>>>>>>>>>> "Tab Atkins Jr." <jackalmage@gmail.com> writes (Wed, 27 Jun
>>>>>>>>>>> 2012 09:10:47 -0700):
>>>>>>>>>>>
>>>>>>>>>>>> On Wed, Jun 27, 2012 at 6:34 AM, Morten Stenshorne  <mstensho@opera.com> wrote:
>>>>>>>>>>>>> Morten Stenshorne <mstensho@opera.com> writes:
>>>>>>>>>>>>>> "Tab Atkins Jr." <jackalmage@gmail.com> writes:
>>>>>>>>>>>>>>> On Mon, Jun 25, 2012 at 1:35 AM, Morten Stenshorne  <mstensho@opera.com> wrote:
>>>>>>>>>>>>>>>> fantasai <fantasai.lists@inkedblade.net> writes (in
>>>>>>>>>>>>>>>> "[CSSWG]  Minutes and Resolutions 2012-06-20"):
>>>>>>>>>>>>>>>>>         - RESOLVED: order affects painting order
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Will 'flex-direction' and 'align-content' also
>>>>>>>>>>>>>>>> affectpainting order then?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> No, neither have any effect on painting order.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Makes sense. Can you update the spec?
>>>>>>>>>>>>>
>>>>>>>>>>>>> But then again I can't really say I'm convinced that it's
>>>>>>>>>>>>> agood thing that 'order' affects painting order at all.
>>>>>>>>>>>>>
>>>>>>>>>>>>>          <div style="display:flex;">
>>>>>>>>>>>>>            <div id="a" style="order:3;">a</div>
>>>>>>>>>>>>>            <div id="b" style="position:relative; order:2;">b</div>
>>>>>>>>>>>>>            <div id="c" style="position:relative;">c</div>
>>>>>>>>>>>>>            <div id="d" style="position:relative; z-index:-1; border:4;">d</div>
>>>>>>>>>>>>>          </div>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Painting order will here be d-a-c-b? So we have two levels of paint
>>>>>>>>>>>>> ordering? Isn't this just confusing?
>>>>>>>>>>>>
>>>>>>>>>>>> Yes, that's the right painting order.  This correctly matches the
>>>>>>>>>>>> visual order, as if you had written it in the order c-b-a-d.
>>>>>>>>>>>>
>>>>>>>>>>>>> (doesn't sound very pleasant to implement, either)
>>>>>>>>>>>>
>>>>>>>>>>>> It was trivial on our side, as we make 'order' literally reorder the
>>>>>>>>>>>> box tree (iiuc).
>>>>>>>>>>>
>>>>>>>>>>> What about this one:
>>>>>>>>>>>
>>>>>>>>>>>         <div style="display:flex;">
>>>>>>>>>>>             <div id="item1" style="position:relative; order:1;margin-left:-5px; border:2px solid blue; background:lime;">
>>>>>>>>>>>             xxx
>>>>>>>>>>>                 <div id="abspos" style="position:absolute;margin-top:-5px; border:2px solid violet; background:cyan;">
>>>>>>>>>>> 	           yyy
>>>>>>>>>>>             </div>
>>>>>>>>>>>           </div>
>>>>>>>>>>>           <div id="item2" style="position:relative;margin-left:-5px; border:2px solid red; background:yellow;">
>>>>>>>>>>>             zzz
>>>>>>>>>>>           </div>
>>>>>>>>>>>         </div>
>>>>>>>>>>>
>>>>>>>>>>> Three positioned elements. One stacking context. In what
>>>>>>>>>>> orderare they painted?
>>>>>>>>>>
>>>>>>>>>> You treat order as if it literally reorders the box tree.  So your
>>>>>>>>>> putting order:1 on item1 (which is already in the first position)
>>>>>>>>>> achieves nothing whatsoever,
>>>>>>>>>
>>>>>>>>> ???
>>>>>>>>>
>>>>>>>>> Initial value of 'order' is 0, so reordering will certainly occur.
>>>>>>>>
>>>>>>>> My bad; I thought it was 1.
>>>>>>
>>>>>>>> So the painting order would be item2 followed by item1 as per the
>>>>>>>> current ED;
>>>>>>
>>>>>>> When is "abspos" painted?
>>>>>>
>>>>>> Well, the abspos doesn't establish a stacking context; it's positioned
>>>>>> but with z-index:auto.  (Hence it establishes a painting context or
>>>>>> pseudo stacking context or whatever we want to call it.) So it
>>>>>> participates in its closest ancestor painting context or stacking
>>>>>> context, as per CSS21.  This ancestor is item1, which is also
>>>>>> positioned with z-index:auto and hence establishes a painting context.
>>>>>>
>>>>>> So as part of CSS21 9.9.1 layer 6 (for things with stack level 0)
>>>>>> you'll be painting item2 first (order:0) and item1 second (order:1),
>>>>>> and as part of painting item1 you'll be painting its abspos child.
>>>>>
>>>>> But "item1" doesn't establish a new stacking context, so "abspos" should
>>>>> be treated separately. It's just another member of the root element's
>>>>> (or viewport's) stacking context, just like "item1" and "item2".
>>>>
>>>> No, that's not how the CSS21 painting order works.  Relpos elements
>>>> with z-index:auto establish a "painting context" or "pseudo stacking
>>>> context", which behave like bona fide stacking contexts except that
>>>> their would-be dependants which themselves establish stacking contexts
>>>> do not in fact participate in the painting context and instead
>>>> participate in their closest ancestor stacking context (which in your
>>>> example is established by the root element).  However, your abspos
>>>> doesn't establish a stacking context because it doesn't have integer
>>>> z-index.  So it participates in the painting context established by
>>>> item1.
>>>
>>> I don't think so.
>>> What the spec says (http://www.w3.org/TR/CSS2/visuren.html#z-index):
>>>
>>> (1)  "Within each stacking context, positioned elements with stack level
>>>        0 (in layer 6), non-positioned floats (layer 4), inline blocks
>>>        (layer 5), and inline tables (layer 5), are painted as if those
>>>        elements themselves generated new stacking contexts,"
>>>
>>> And it goes on like this - the crucial part:
>>>
>>> (2)  "except that their positioned descendants and any would-be child
>>>         stacking contexts take part in the current stacking context."
>>
>> You're right.  (This hasn't been my day, really, has it? :-( Sorry.)
>
> ;)
>
> It's complicated.

Thanks, but that's not much of an excuse given that I half rewrote 9.9.1 
;-).  I was simply sure that I had it right today and didn't bother 
looking it up (something that I almost always end up regretting!). Sorry 
for the confusion that I introduced.

>> The fact that /all/ positioned elements "bubble up", not just the ones
>> which establish stacking contexts, was a change to the spec from a
>> long time ago, motivated by excellent interop at that time.
>
> I don't remember when that happened, but it's really really long ago, I
> suppose?

End of 2007: http://wiki.csswg.org/spec/css2.1#issue-17

> Actually, too bad it happened. Letting each positioned element establish
> a stacking context would have been so much simpler. And then we wouldn't
> even have needed this discussion. :)
>
>>> (3)  "Boxes with the same stack level in a stacking context are stacked
>>>        back-to-front according to document tree order."
>>
>>> According to (3), painting order should simply be "item1", "abspos",
>>> "item2",
>> Yes, they're all in layer 6 for stack level 0 elements, within the
>> root stacking context.
>>
>>> but because of the 'order' property, "item2" should be painted
>>> before "item1".
>>
>> Yes, I agree.
>>
>>> This is where I get problems. Where does "abspos" go?
>>>
>>> item2-item1-abspos?
>>> abspos-item2-item1?
>>
>> The former.  The flexbox ED says:
>>
>>    # This also affects the painting order [CSS21], exactly as if the
>>    # elements were reordered in the document.
>>
>>> It seems weird to follow tree order for "abspos" here, although that
>>> would be closer to the spec.
>>
>> I think I see what you're getting at now.  You're saying that the spec
>> isn't clear whether it's just the element itself that is painted in a
>> new order, rather than the subtree rooted at the element?
>
> Yes.

OK. Perhaps the editors can make that clearer in the flexbox spec.

> And by "spec" I meant CSS21.

Well, I don't think we need to tie ourselves so closely to CSS21 that we 
end up introducing unnecessary complexity.  Subtree reordering is fairly 
easy to grasp; easier than the idea of reordering lone elements but 
somehow leaving their descendents in their original tree position, I 
would think.

>> It never occurred to me to interpret the spec as describing anything
>> other than subtree reordering.
>
> That makes sense, apart from the fact that it violates CSS21 a bit
> more. That was my thinking, anyway. I still feel uncomfortable with
> letting 'order' affect painting order, but maybe it will finally occur
> to me as a very natural thing in a few months time. :)

I definitely violates CSS21, but I don't think that's a problem so long 
as it's well defined and not unnecessarily complex.  Of course, 
everyone's mileage varies when it comes to defining "unnecessarily". I'm 
generally comfortable with letting 'order' affect painting order (for 
entire subtrees), but I wouldn't die on its behalf either!

Cheers,
Anton Prowse
http://dev.moonhenge.net
Received on Friday, 20 July 2012 15:44:51 GMT

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