Skip to content

Commit cca6f26

Browse files
authored
Merge pull request #3750 from mattwoodrow/3d-rendering-model
[css-transforms-2] Revert to the TR rendering model, where transform-style:preserve-3d establishes the 3d rendering context. #1950
2 parents 80e08c7 + 7555b67 commit cca6f26

File tree

2 files changed

+55
-42
lines changed

2 files changed

+55
-42
lines changed

css-transforms-2/Overview.bs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ New transform functions for the 'transform' property allow three-dimensional tra
5151
and additional properties make working with three-dimensional transforms easier,
5252
and allow the author to control how nested three-dimensional transformed elements interact.
5353

54-
1. The 'perspective' property allows the author to make child elements with three-dimensional transforms appear as if they live in a common three-dimensional space. The 'perspective-origin' property provides control over the origin at which perspective is applied, effectively changing the location of the "vanishing point".
54+
1. The 'perspective' property allows the author to provide child elements with an extra perspective transformation. The 'perspective-origin' property provides control over the origin at which perspective is applied, effectively changing the location of the "vanishing point".
5555

5656
2. The 'transform-style' property allows 3D-transformed elements and their 3D-transformed descendants to share a common three-dimensional space, allowing the construction of hierarchies of three-dimensional objects.
5757

@@ -177,9 +177,10 @@ Three-dimensional transform functions extend this coordinate space into three di
177177
3D Transform Rendering {#3d-transform-rendering}
178178
----------------------
179179

180-
Normally, elements render as flat planes, and are rendered into the same plane as their containing block. Often this is the plane shared by the rest of the page. Two-dimensional transform functions can alter the appearance of an element, but that element is still rendered into the same plane as its containing block.
180+
Normally, elements render as flat planes, and are rendered into the same plane as their stacking context. Often this is the plane shared by the rest of the page. Two-dimensional transform functions can alter the appearance of an element, but that element is still rendered into the same plane as its stacking context.
181181

182-
Three-dimensional transforms can result in transformation matrices with a non-zero Z component (where the Z axis projects out of the plane of the screen). This can result in an element rendering on a different plane than that of its containing block. This may affect the front-to-back rendering order of that element relative to other elements, as well as causing it to intersect with other elements.
182+
An element with a three-dimensional transform that is not contained in a <a>3D rendering context</a> renders with the appropriate transform applied, but does not intersect with any other elements. The three-dimensional transform in this case can be considered just as a painting effect, like two-dimensional transforms. Similarly, the transform does not affect painting order. For example, a transform with a positive Z translation may make an element look larger, but does not cause that element to
183+
render in front of elements with no translation in Z.
183184

184185
<div class="example">
185186

@@ -278,11 +279,21 @@ This section specifies the rendering model for content that uses 3D-transforms a
278279

279280
A <a>3D rendering context</a> is a set of elements rooted in a common ancestor that, for the purposes of 3D-transform rendering, are considered to share a common three-dimensional coordinate system. The front-to-back rendering of elements in the a 3D rendering context depends on their z-position in that three-dimensional space, and, if the 3D transforms on those elements cause them to intersect, then they are rendered with intersection.
280281

281-
A 3D rendering context is established by an element which has a used value for transform-style of "flat". Descendant elements with a used value for transform-style of "auto" or "preserve-3d" share their enclosing 3D rendering context. A descendant with a used value for transform-style of "flat" participates in its containing 3D rendering context, but establishes a new 3D rendering context for its descendants. For the purposes of rendering in its containing 3D rendering context, it behaves like a flat plane.
282+
The position of each element in that three-dimensional space is determined by accumulating the transformation matrices up from the given element to the element that establishes the <a>3D rendering context</a>.
282283

283-
Note: This is conceptually similar to CSS stacking contexts. A positioned element with explicit z-index establishes a stacking context, while participating in the stacking context of an ancestor. Similarly, an element can establish a 3D rendering context for its descendants, while participating in the 3D rendering context of an ancestor. Just as elements within a stacking context render in z-index order, elements in a 3D-rendering context render in z-depth order and can intersect.
284+
Elements establish and participate in 3D rendering contexts as follows:
284285

285-
Some CSS properties have values that are considered to force "grouping": they require that their element and its descendants are rendered as a group before being composited with other elements; these include opacity, filters and properties that affect clipping. The relevant property values are listed under <a href="#grouping-property-values">grouping property values</a>. These grouping property values force the used value for transform-style to be "flat", and such elements are referred to as <dfn>flattening elements</dfn>. Consequently, they always establish a new 3D rendering context. The root element always has a used value of "flat" for transform-style.
286+
287+
* A <a>3D rendering context</a> is established by a <a>transformable element</a> whose used value for 'transform-style' is ''transform-style/preserve-3d'' and which itself is not part of a 3D rendering context. An element that establishes a 3D rendering context also participates in that context.
288+
* An element whose used value for 'transform-style' is ''transform-style/preserve-3d'' and which itself participates in a <a>3D rendering context</a>, extends that 3D rendering context rather than establishing a new one.
289+
* An element participates in a <a>3D rendering context</a> if its parent establishes or extends a <a>3D rendering context</a>.
290+
291+
292+
Some CSS properties have values that are considered to force "grouping": they require that their element and its descendants are rendered as a group before being composited with other elements; these include opacity, filters and properties that affect clipping. The relevant property values are listed under <a href="#grouping-property-values">grouping property values</a>. Consequently, when used on an element with transform-style:preserve-3d, they change the used value to
293+
''transform-style/flat'' and prevent it from creating or extending a <a>3D rendering context</a>.
294+
295+
Issue: This doesn't describe how untransformed content within a 3D transformed element is handled, the alogrithm probably needs to be recursive.
296+
Issue: Figure out what the current behaviour of various engines is, and figure out a clearer description that wont break web compat.
286297

287298
The rendering of elements in a 3D rendering context is as follows (numbers refer to items in <a href="https://www.w3.org/TR/CSS2/zindex.html#painting-order">CSS 2.1, Appendix E, Section E.2 Painting Order</a>):
288299

@@ -305,10 +316,13 @@ Note: Because the 3D-transformed elements in a 3D rendering context can all dept
305316
<div class="example">
306317
<pre>
307318
&lt;style>
308-
.container {
319+
.scene {
309320
background-color: rgba(0, 0, 0, 0.3);
310321
perspective: 500px;
311322
}
323+
.container {
324+
transform-style: preserve-3d;
325+
}
312326
.container > div {
313327
position: absolute;
314328
left: 0;
@@ -327,23 +341,21 @@ Note: Because the 3D-transformed elements in a 3D rendering context can all dept
327341
}
328342
&lt;/style>
329343

330-
&lt;div class="container">
331-
&lt;div>&lt;/div>
332-
&lt;div>&lt;/div>
344+
&lt;div class="scene">
345+
&lt;div class="container">
346+
&lt;div>&lt;/div>
347+
&lt;div>&lt;/div>
348+
&lt;/div>
333349
&lt;/div>
334350
</pre>
335351

336-
This example shows show elements in a 3D rendering context can intersect. The container element establishes a 3D rendering context for itself and its two children. The children intersect with each other, and the orange element also intersects with the container.
352+
This example shows show elements in a 3D rendering context can intersect. The container element establishes a 3D rendering context for itself and its two children, and the scene element adds perspective to the 3D rendering context. The children intersect with each other, and the orange element also intersects with the container.
337353

338354
<div class="figure">
339355
<img src="examples/3d-intersection.png" width="210" height="198" alt="Intersecting sibling elements.">
340356
</div>
341357
</div>
342358

343-
The ''perspective'' property can be used to ensure that 3D transformed elements in the resulting 3D rendering context appear to live in a common three-dimensional space with depth, by suppling a common perspective matrix to descendant transformed members of its 3D rendering context, which is taken into account in the <a href="#accumulated-3d-transformation-matrix-computation">accumulated 3D matrix computation</a>.
344-
345-
By default, elements with value for ''perspective'' other than ''perspective/none'' are [=flattening element|flattening=], and thus establish a 3D rendering context. However, setting ''transform-style'' to ''preserve-3d'' allows the perspective element to extend its containing 3D rendering context (provided no other <a href="#grouping-property-values">grouping property values</a> are in effect).
346-
347359
<div class="example">
348360
<pre>
349361
&lt;style>
@@ -382,7 +394,7 @@ This example shows how nested 3D transforms are rendered. The blue div is transf
382394

383395
### Transformed element hierarchies ### {#transformed-element-hierarchies}
384396

385-
By default, <a>transformed elements</a> are [=flattening element|flattening=], and thus establish a <a>3D rendering context</a>. However, since it is useful to construct hierarchies of transformed objects that share a common 3-dimensional space, this flattening behavior may be overridden by specifying a value of ''preserve-3d'' for the ''transform-style'' property, provided no other <a href="#grouping-property-values">grouping property values</a> are in effect. This allows descendants of the transformed element to share the same 3D rendering context. Non-3D-transformed descendants of such elements are rendered into the plane of the element in step C above, but 3D-transformed elements in the same 3D rendering context will "pop out" into their own planes.
397+
By default, <a>transformed elements</a> do not create a <a>3D rendering context</a> and create a flattened representation of their content. However, since it is useful to construct hierarchies of transformed objects that share a common 3-dimensional space, this flattening behavior may be overridden by specifying a value of ''preserve-3d'' for the ''transform-style'' property. This allows descendants of the transformed element to share the same 3D rendering context. Non-3D-transformed descendants of such elements are rendered into the plane of the element in step C above, but 3D-transformed elements in the same 3D rendering context will "pop out" into their own planes.
386398

387399
<div class="example">
388400
<pre>
@@ -421,22 +433,22 @@ The final value of the transform used to render an element in a <a>3D rendering
421433

422434
1. Let <var>transform</var> be the identity matrix.
423435
2. Let <var>current element</var> be the transformed element.
424-
3. Let <var>ancestor block</var> be the element that establishes the transformed element's containing block.
436+
3. Let <var>parent element</var> be the parent element of the transformed element.
425437
4. While <var>current element</var> is not the element that establishes the transformed element's <a>3D rendering context</a>:
426438

427439
1. If <var>current element</var> has a value for 'transform' which is not ''transform/none'', pre-multiply <var>current element</var>'s <a>transformation matrix</a> with the <var>transform</var>.
428-
2. Compute a translation matrix which represents the offset of <var>current element</var> from its <var>ancestor block</var>, and pre-multiply that matrix into the <var>transform</var>.
429-
3. If <var>ancestor block</var> has a value for 'perspective' which is not ''perspective/none'', pre-multiply the <var>ancestor block</var>'s <a>perspective matrix</a> into the <var>transform</var>.
430-
4. Let <var>ancestor block</var> be the element that establishes the <var>current element</var>'s containing block.
431-
5. Let <var>current element</var> be the <var>ancestor block</var>.
440+
2. Compute a translation matrix which represents the offset of <var>current element</var> from its <var>parent element</var>, and pre-multiply that matrix into the <var>transform</var>.
441+
3. If <var>parent element</var> has a value for 'perspective' which is not ''perspective/none'', pre-multiply the <var>parent element</var>'s <a>perspective matrix</a> into the <var>transform</var>.
442+
4. Let <var>current element</var> be the <var>parent element</var>.
443+
5. Let <var>parent element</var> be the <var>current element</var>'s parent.
432444

433445
Note: as described here, the <a>accumulated 3D transformation matrix</a> takes into account offsets generated by the <a href="https://www.w3.org/TR/REC-CSS2/visuren.html">visual formatting model</a> on the transformed element, and elements in the ancestor chain between the transformed element and the element that establishes the its <a>3D rendering context</a>.
434446

435447
### Backface Visibility ### {#backface-visibility}
436448

437449
Using three-dimensional transforms, it's possible to transform an element such that its reverse side is visible. 3D-transformed elements show the same content on both sides, so the reverse side looks like a mirror-image of the front side (as if the element were projected onto a sheet of glass). Normally, elements whose reverse side is towards the viewer remain visible. However, the 'backface-visibility' property allows the author to make an element invisible when its reverse side is towards the viewer. This behavior is "live"; if an element with ''backface-visibility: hidden'' were animating, such that its front and reverse sides were alternately visible, then it would only be visible when the front side were towards the viewer.
438450

439-
Visibility of the reverse side of an element is considered using the <a>accumulated 3D transformation matrix</a>, and is thus relative to the enclosing [=flattening element=].
451+
Visibility of the reverse side of an element is considered using the <a>accumulated 3D transformation matrix</a>, and is thus relative to the parent of the element that establishes the <a>3D rendering context</a>.
440452

441453
Note: This property is useful when you place two elements back-to-back, as you would to create a playing card. Without this property, the front and back elements could switch places at times during an animation to flip the card. Another example is creating a box out of 6 elements, but where you want to see only the inside faces of the box.
442454

@@ -730,21 +742,22 @@ The 'transform-style' Property {#transform-style-property}
730742

731743
<pre class='propdef'>
732744
Name: transform-style
733-
Value: auto | flat | preserve-3d
734-
Initial: auto
745+
Value: flat | preserve-3d
746+
Initial: flat
735747
Applies to: <a>transformable elements</a>
736748
Inherited: no
737749
Percentages: N/A
738750
Computed value: specified keyword
751+
Used value: flat if a <a href="#grouping-property-values">grouping property</a> is present, specified keyword otherwise
739752
Animation type: discrete
740753
</pre>
741754

742-
A value of "flat" for 'transform-style' establishes a stacking context, and establishes a <a>3D rendering context</a>. Elements with a used value of "auto" are ignored for the purposes of 3D rendering context computation, and those with a used value of "preserve-3d" extend the 3D rendering context to which they belong, even if values for the ''transform'' or ''perspective'' properties would otherwise cause flattening. A value of "preserve-3d" establishes a stacking context, and a [=containing block for all descendants=].
755+
A computed value of ''transform-style/preserve-3d'' for 'transform-style' establishes both a stacking context and a [=containing block for all descendants=]. If the used value is ''transform-style/preserve-3d'' then it also establishes or extends a <a>3D rendering context</a>.
743756

744757
Grouping property values {#grouping-property-values}
745758
------------------------
746759

747-
The following CSS property values require the user agent to create a flattened representation of the descendant elements before they can be applied, and therefore force the used value of ''transform-style'' to ''flat'':
760+
The following CSS property values require the user agent to create a flattened representation of the descendant elements before they can be applied, and therefore force the element to have a used style of ''transform-style/flat'' for 'preserve-3d'.
748761

749762
* 'overflow': any value other than ''overflow/visible'' or ''overflow/clip''.
750763
* 'opacity': any value less than 1.
@@ -756,17 +769,6 @@ The following CSS property values require the user agent to create a flattened r
756769
* 'mask-border-source': any value other than ''mask-border-source/none''.
757770
* 'mix-blend-mode': any value other than ''mix-blend-mode/normal''.
758771

759-
The following CSS property values cause an ''transform-style/auto'' value of ''transform-style'' to become ''transform-style/flat'':
760-
761-
* 'transform': any value other than ''transform/none''.
762-
* 'perspective': any value other than ''perspective/none''.
763-
764-
In both cases the computed value of 'transform-style' is not affected.
765-
766-
Issue: Having overflow imply transform-style: flat causes every element with non-visible/clip overflow to become
767-
a stacking context, which is unwanted. See <a href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=28252">Bug 28252</a>.
768-
769-
770772
The 'perspective' Property {#perspective-property}
771773
==========================
772774

@@ -802,6 +804,8 @@ Animation type: by computed value
802804

803805
The use of this property with any value other than ''perspective/none'' establishes a stacking context. It also establishes a [=containing block for all descendants=], just like the 'transform' property does.
804806

807+
Issue: We don't really need to be a stacking context or containing block for perspective, but maybe webcompat means we can't change this.
808+
805809
The values of the 'perspective' and 'perspective-origin' properties are used to compute the <a>perspective matrix</a>, as described above.
806810

807811

css-transforms-2/examples/3d-intersection.html

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
height: 150px;
99
width: 150px;
1010
}
11-
.container {
11+
.scene {
1212
border: 1px solid black;
1313
margin: 20px;
1414
padding: 10px;
@@ -19,6 +19,13 @@
1919
-o-perspective: 500px;
2020
perspective: 500px;
2121
}
22+
.container {
23+
-webkit-transform-style: preserve-3d;
24+
-moz-transform-style: preserve-3d;
25+
-ms-transform-style: preserve-3d;
26+
-o-transform-style: preserve-3d;
27+
transform-style: preserve-3d;
28+
}
2229

2330
.container > div {
2431
position: absolute;
@@ -48,10 +55,12 @@
4855
</style>
4956
</head>
5057
<body>
51-
<div class="container">
52-
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
53-
<div></div>
54-
<div></div>
58+
<div class="scene">
59+
<div class="container">
60+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
61+
<div></div>
62+
<div></div>
63+
</div>
5564
</div>
5665
</body>
5766
</html>

0 commit comments

Comments
 (0)