Re: [css-transforms] Unify the definition of transform-style & 3D context

transform-style:auto is only one minor difference. Its purpose is to
tell an element to "preserve 3D, but don't create stacking context or
containing block". For example:

<div>
    <div style="transform:blah;"></div>
    <div style="transform:blah;"></div>
</div>
<div style="transform:blah;"></div>

The <div> with default attributes had default transform-style:flat
back in TR spec. However the WebKit implementation didn't really
flatten anything, and web developers intuitively expected it to be
no-op. Here is where transform-style:auto came in.

In my proposal, normal flow & pseudo stacking context (z-index:auto)
elements don't interact with 3D at all. They effectively act like
transform-style:auto.

The bigger differences are

1. How 3D contexts are grouped. A minimal example:

<div id=A" style="transform-style:flat; position:relative; z-index:0;">
    <div id="B" style="transform-style:preserve-3d;
transform:translateZ(10px);"></div>
    <div id="C" style="transform-style:preserve-3d;
transform:translateZ(-10px);"></div>
</div>

Should B and C depth-sorted against each other?
Chromium says no, because A is a regular stacking context, so B and C
sort by normal z-index.
WebKit says yes, because A flattens the 3D context shared by all children.
Firefox acts weirdly when you added a third children. I couldn't
really understand its behavior.

2. Who is the owner (root) of a 3D context.
In ED/WebKit's definition, a 3D context can only be owned by someone
who has transform-style:flat.
In my proposal, a 3D context can only be owned by someone who has
transform-style:preserve-3d.

3. How to find the root of a 3D context from an element
In ED/WebKit's definition, travels up the containing block chain and
find the first transform-style:flat. (Ill-defined due to containing
block penetration.)
In my proposal, travels up the stacking context chain, and find last
transform-style:preserve-3d before hitting root or
transform-style:flat. As transform-style:preserve-3d also requires
layout containing, things in the same 3D context are guaranteed to
have common containing block ancestor too.

On Wed, Sep 28, 2016 at 8:49 PM, Rik Cabanier <cabanier@gmail.com> wrote:
> This is obviously a very hard problem. :-)
>
> Tien-Ren,
> your proposal seems to be close to smfr, except he used 'transform-style:
> auto' as the default value.
> That way, an element's 3d behavior can depend on the value of parent and
> children.
>
> Does this match Chrome's implementation, or is it what you'd like it to be?
>
>
> Rik
>
> On Tue, Sep 27, 2016 at 3:25 PM, Tien-Ren Chen <trchen@chromium.org> wrote:
>>
>> On Mon, Sep 26, 2016 at 6:07 PM, Matt Woodrow <mwoodrow@mozilla.com>
>> wrote:
>> >
>> >
>> > On 27/09/16 1:12 PM, Tien-Ren Chen wrote:
>> >>
>> >> I'm particularly worrying about this case:
>> >>
>> >> <style> div { transform-style: preserve-3d; } </style>
>> >> <div>
>> >>      A
>> >>      <div style="transform:translateZ(0);">B</div>
>> >>      <div style="position:relative; z-index:0;">C</div>
>> >> </div>
>> >>
>> >> If we don't make the distinction between 2D/3D (i.e. no plane / new
>> >> plane), the transition between translateZ(-epsilon), translateZ(0),
>> >> and translateZ(epsilon) could be tricky. IMO B should be popped into
>> >> its own plane, and perform depth-sorting against plane AC as a whole.
>> >
>> > What would be the intended result of depth sorting in this case? They
>> > both
>> > have 0 depth, no z-index and now the content order is undefined since AC
>> > is
>> > both before and after B.
>> >
>> > I prefer having B transition to being between A and C while the Z
>> > translation is 0.
>>
>> In my opinion, tie breaking should use the order of root background
>> phase in stacking context order, that is, B on top of AC when z=0.
>>
>> There are a number of issues for transition to be in between A and C:
>> 1. I really don't think that's what 3D web developers want. Fusion of
>> planes can be really counter-intuitive at times. For example:
>> http://jsbin.com/xoradus/ (Note: Chromium doesn't even rendering this
>> correctly. Please open with Firefox.)
>> 2. Higher runtime cost. A and C will need to be cached in separate
>> buffer,  more buffer to composite, and more polygons need to be
>> partitioned.
>> 3. Numerical issue. It is difficult to decide whether two matrices are
>> co-planar. For example, rotateY(30deg)translateZ(10px) and
>> rotateY(30deg)translateZ(10px)rotateZ(30deg) are obviously coplanar,
>> but their computed normal vector is likely to differ by a few ulps. In
>> Chromium we used a tolerance value, but that created another class of
>> issues.
>>
>> >> Another weird case:
>> >>
>> >> <style> div { transform-style: preserve-3d; } </style>
>> >> <div id="A" style="background:some_image; translateZ(0);">
>> >>      Foreground
>> >>      <div id="B" style="transform:translateZ(0); position:relative;
>> >> z-index:-1;">Stuck in middle?</div>
>> >> </div>
>> >>
>> >> Should B to stack in between the background/foreground of A because it
>> >> has negative z-index? I think the sensible thing to do is to pop it to
>> >> its own plane.
>> >
>> > I'm not sure I understand this case fully. It makes sense to me that B
>> > would
>> > be in the middle, z-index applies within the current stacking context,
>> > putting B before Foreground.
>>
>> Yes, with no doubt things should behave as you just described if
>> everything have transform-style:flat.
>>
>> However my two cents is that we should double think what would be the
>> most useful and intuitive behavior with transform-style:preserve-3d.
>> With preserve-3d, the subtree won't be atomic / in an isolated group
>> anyway.
>
>

Received on Thursday, 29 September 2016 22:42:35 UTC