- From: Tien-Ren Chen <trchen@chromium.org>
- Date: Wed, 21 Sep 2016 17:03:04 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: Matt Woodrow <mwoodrow@mozilla.com>, Rik Cabanier <cabanier@gmail.com>, "/#!/JoePea" <trusktr@gmail.com>, Chris Harrelson <chrishtr@google.com>, Simon Fraser <simon.fraser@apple.com>, "public-fx@w3.org" <public-fx@w3.org>
On Wed, Sep 21, 2016 at 12:02 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote: > translateZ() and z-index should > work similarly, as they're doing the same thing. I don't agree with you. IMO a 3D transform should pop the subtree to a new plane if inside of a 3D context. e.g. <style> div { transform-style: preserve-3d; } </style> <div style="position:relative; z-index:0;"> Plane A <div style="transform:translateZ(0);">Plane B</div> <div style="z-index:1;">Plane A too</div> </div> Should be treated the same as: <style> div { transform-style: preserve-3d; } </style> <div style="position:relative; z-index:0;"> Plane A <div style="z-index:1;">Plane A too</div> </div> <div style="transform:translateZ(0);">Plane B</div> This will avoid having to deal with the transition between translateZ(-epsilon) / translateZ(0) / translateZ(epsilon) in case of an animation, which incurs a huge runtime cost because every stacking context after a transformed child will need to be cached separately. In my mental model, this is how a compositing tree should look like: Output = StackingContext StackingContext = NormalFlowBackground + Child* + NormalFlowForeground + Child* [#1] || flatten( 3dContext ) || grouping_property( StackingContext ) Child = StackingContext || PseudoStackingContext PseudoStackingContext = NormalFlowBackground + NormalFlowForeground 3dContext = Plane* Plane = StackingContext, Matrix44 Note #1: Operator+ is our typical src-over. In case of CSS blending, replace operator+ with appropriate operator. Basically each StackingContext physically is an array of RGBA pixels. Combined with a Matrix44 give each pixel a depth, each Plane physically is an array of RGBAD pixels. Flattening operation takes a list of planes, and src-over (or blend) each pixels depth-sorted (in case of a tie, stacking context order is used to break the tie.). The actual implementation will most likely do polygon splitting, as performing a sort on each pixel over a number of planes would be prohibitively expensive. And I would spec the painting order of elements with this decision tree: ---- z-index: auto --- 1. An element paints as the normal flow of the current (pseudo) stacking context if the element has z-index:auto and position:static. 2. An element establishes a pseudo stacking context if it has z-index:auto and position other than static. This new pseudo stacking context sorts into current stacking context as if z-index is 0. --- non-auto z-index, with no 3D[#2] transform --- 3. An element establishes a stacking context if it has non-auto z-index and no 3D transform. This new stacking context become the current stacking context and sorts into previous stacking context by z-index value. --- 3D transformed --- 4. An element establishes a stacking context if it has 3D transform and both itself and its containing block have transform-style:flat. The depth part of the transform is discarded and behave like case 3. 5. An element establishes a plane and a stacking context if it has 3D transform and its containing block has transform-style:preserve-3d. This new plane joins the current 3D context, and the new stacking context becomes the root stacking context of the new plane. The z-index is unused except for tie breaking. 6. An element establishes a 3D context, a plane and a stacking context if it has transform-style:preserve-3d and its containing block has transform-style:flat. This new 3D context will flatten its planes and become a child stacking context that sorts into current stacking context by z-index value. This new plane joins the new 3D context, and the new stacking context becomes the root stacking context of the new plane. [#3] Note #2: There is a discrepancy in the definition of 3D-ness of transforms. Firefox & Edge uses the computed local matrix. Blink & WebKit see whether a 3D operation is used in the property. Note #3: We can see in this case actually two stacking contexts are created. It is unspecified in the current spec whether grouping properties apply to the flattened output or the root stacking context of the new plane. Behavior is inconsistent across vendors.
Received on Thursday, 22 September 2016 00:03:38 UTC