- From: Tien-Ren Chen <trchen@chromium.org>
- Date: Mon, 26 Sep 2016 16:22:57 -0700
- To: public-fx@w3.org
- Cc: Simon Fraser <simon.fraser@apple.com>, "Tab Atkins Jr." <jackalmage@gmail.com>, Rik Cabanier <cabanier@gmail.com>, Matt Woodrow <mwoodrow@mozilla.com>
As a spin-off discussion from "[css-transforms] CSS3D breaks with opacity flattening". Rik suggested me to file an issue to clarify the definition of planes and how 3D content stacks together. Before we start to define "planes", I think we should first start off with the very basic definition of transform-style and 3D context, which is a complete mess right now. I think it is pointless to discuss anything else if we are not on the same page about which elements live in the same space. Here is a strikingly simple example to show what a mess it is: http://jsbin.com/doyedeg/ <div style="transform-style:flat; width:100px; height:100px; opacity:0.5; background:red;"> <div style="transform-style:preserve-3d; width:100px; height:100px; margin-left:50px; background:green; transform:translateZ(0);"></div> <div style="transform-style:preserve-3d; width:100px; height:100px; margin-left:25px; margin-top:-50px; background:blue; transform:translateZ(-1px);"></div> </div> 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). 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.
Received on Monday, 26 September 2016 23:23:27 UTC