- From: Tien-Ren Chen <trchen@chromium.org>
- Date: Mon, 26 Sep 2016 17:12:54 -0700
- To: Matt Woodrow <mwoodrow@mozilla.com>
- Cc: public-fx@w3.org, Simon Fraser <simon.fraser@apple.com>, "Tab Atkins Jr." <jackalmage@gmail.com>, Rik Cabanier <cabanier@gmail.com>
On Mon, Sep 26, 2016 at 4:50 PM, Matt Woodrow <mwoodrow@mozilla.com> wrote: > > On 27/09/16 12:22 PM, Tien-Ren Chen wrote: >> >> As I summed up in row 2~4 of my comparison sheet >> (https://goo.gl/5dgFza), Chromium, Firefox, and Safari stack the >> layers all differently (RGB, RBG, BRG, respectively) because they >> create 3D context differently. An oversimplified explanation is that >> Chromium followed the TR spec, Safari followed the ED spec, while >> Firefox stuck somewhere in between (but closer to TR in general). > > > Firefox is meant to the follow the TR spec. It looks like we have a bug > where we combine sibling preserve-3d contexts for sorting and we shouldn't. > > >> I studied many of the unspecified corner cases as I worked on >> Chromium's clean-room compositing implementation (a.k.a. SPv2), I feel >> strongly that the ED's definition is a no-go, because it introduced >> the "3D context penetration issue". For example, "6.1.4. Accumulated >> 3D Transformation Matrix Computation"(https://goo.gl/oKQpm2) is >> ill-defined if the 3D-context-establishing element is not a containing >> block. >> >> In my opinion TR's definition is way more self-consistent, although it >> does need some clarification. I would rephrase it this way: >> >> transform-style is only applicable to elements that creates a stacking >> context (i.e. with non-auto used z-index), as it modifies stacking >> context behavior. The default value is 'flat'. A computed value of >> 'preserve-3d' forces stacking context, and establishes containing >> block for all descendants. >> >> A stacking context with transform-style:flat works like a traditional >> stacking context, sorting its child stacking contexts by their >> z-index. If a child stacking context has 3D transform, the depth >> component resulting from the transform is unused. >> >> A stacking context with transform-style:preserve-3d propagates up >> descendant planes created by 3D transforms if the parent stacking >> context also has transform-style:preserve-3d. If its parent stacking >> context has transform-style:flat, the inherited screen-space matrix >> gets flattened. The collection of planes are sorted by depth and >> composited with src-over. >> >> To summarize, we have the following cases for an element: >> A. z-index:auto && position:static : Normal flow >> B. z-index:auto && !position:static : Pseudo stacking context >> C. !z-index:auto && transform-style:flat && !3D-transformed: >> Traditional stacking context, sorted child stacking contexts by >> z-index. >> D. transform-style:preserve-3d && parentSC.transform-style:flat : >> Establishes 3D context. The flattened result sort with sibling >> stacking contexts by its z-index. Establishes a default plane and root >> stacking context for that plane. >> E. transform-style:preserve-3d && >> parentSC.transform-style:preserve-3d: Inherit 3D context >> >> Also if an element has 3D transform [#1] and it's parent stacking >> context has transform-style:preserve-3d, its stacking context subtree >> gets popped into a plane thus are not sorted against other sibling >> stacking contexts. Its z-index is unused except for tie-breaking. >> >> Note [#1]: A transform is 3D if and only if it contains any 3D >> operation, even if if the computed local matrix has no depth >> component. For example translateZ(0) is considered 3D. > > Why does C need to be !3D-transformed? I don't think the transform on the > element with transform-style:flat changes the rendering of its children. My bad. I meant to explain in a separate case that when with 3D transform presents, transform-style:flat, and parentSC.transform-style:flat, the whole thing still behave like a traditional stacking context, and the depth component of the transform is ignored. > I also don't think we need to have the 2D/3D distinction in the spec. If the > leaf element has a 2D transform and its parent stacking context has > transform-style:preserve-3d, then we still want it to take part in depth > sorting. 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. 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. > > - Matt >
Received on Tuesday, 27 September 2016 00:13:30 UTC