Skip to content

Commit 8700981

Browse files
authored
[css-view-transitions-2] Add nested view transition groups spec (#13412)
* Add nested view transition groups spec
1 parent 0937fdf commit 8700981

File tree

1 file changed

+159
-112
lines changed

1 file changed

+159
-112
lines changed

css-view-transitions-2/Overview.bs

Lines changed: 159 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ spec:css2; type:dfn; text:viewport
131131
and more specifically based on the active view transition being of a certain type.
132132
* [[#shared-style-with-vt-classes|Sharing styles between view transition pseudo-elements]], a way to declare a style once,
133133
and use it for multiple view transition pseudo-elements. This includes the 'view-transition-class' property, and [[#pseudo-element-class-additions|additions to named pseudo-elements]]
134-
* [[#nested-vt|Nested view transition groups]], a way to construct deeper hierarchies of view transition pseudo-elements,
134+
* [[#view-transition-group-prop|Nested view transition groups]], a way to construct deeper hierarchies of view transition pseudo-elements,
135135
which in turn allows relative transforms and clipping of participating elements.
136136
* [[#scoped-vt|Scoped view transitions]], a way to perform view transitions within the scope of a DOM subtree.
137137

@@ -1024,9 +1024,127 @@ the active view transition of an element is exposed to script via a property on
10241024
[=document-scoped view transition names=] don't accidentally interfere with
10251025
other [=scoped view transitions=] in the ancestor chain.
10261026

1027-
# Nested View Transition Groups # {#nested-vt}
1027+
## Nested View Transition Groups: The 'view-transition-group' property ## {#view-transition-group-prop}
10281028

1029-
ISSUE: This needs to be explained / specified.
1029+
<pre class=propdef>
1030+
Name: view-transition-group
1031+
Value: normal | contain | nearest | <<custom-ident>>
1032+
Initial: normal
1033+
Inherited: no
1034+
Percentages: n/a
1035+
Computed Value: as specified
1036+
Animation type: discrete
1037+
</pre>
1038+
1039+
The 'view-transition-group' property can be used in conjuction with 'view-transition-name' to generate a hierarchy of [=named view transition pseudo-element=].
1040+
This property has no effect if 'view-transition-name' is ''view-transition-name/none''.
1041+
1042+
<dl dfn-type=value dfn-for=view-transition-group>
1043+
: <dfn>normal</dfn>
1044+
:: The ''view-transition-group()'' [=pseudo-element=]
1045+
generated by this element
1046+
is a child of the ''view-transition-group-children()'' [=pseudo-element=]
1047+
generated by this element's nearest ''view-transition-group()'' generating
1048+
[=flat tree=] ancestor element
1049+
with a non-''view-transition-group/normal'' 'view-transition-group' value,
1050+
if any.
1051+
If no such element is present, the ''view-transition-group()'' [=pseudo-element=]
1052+
generated by this element
1053+
is a direct child of the ''::view-transition'' [=pseudo-element=]
1054+
associated with this view transition.
1055+
: <dfn>contain</dfn>
1056+
:: The ''view-transition-group-children()'' [=pseudo-element=]
1057+
generated by this element acts as a container for its descendants.
1058+
See ''view-transition-group/normal'' for the effect it has on other elements.
1059+
: <dfn>nearest</dfn>
1060+
:: The ''view-transition-group()'' [=pseudo-element=]
1061+
generated by this element
1062+
is a child of the ''view-transition-group-children()'' [=pseudo-element=]
1063+
generated by this element's nearest ''view-transition-group()'' generating
1064+
[=flat tree=] ancestor element,
1065+
if any.
1066+
If no such element is present, the ''view-transition-group()'' [=pseudo-element=]
1067+
generated by this element
1068+
is a direct child of the ''::view-transition'' [=pseudo-element=]
1069+
associated with this view transition.
1070+
: <dfn><<custom-ident>></dfn>
1071+
:: The ''view-transition-group()'' [=pseudo-element=]
1072+
generated by this element
1073+
is a child of the ''view-transition-group()'' [=pseudo-element=]
1074+
generated by this element's [=flat tree=] ancestor element
1075+
with a ''view-transition-name'' value that matches '<<custom-ident>>', if any.
1076+
If no such element is present, the ''view-transition-group()'' [=pseudo-element=]
1077+
generated by this element
1078+
is a direct child of the ''::view-transition'' [=pseudo-element=]
1079+
associated with this view transition.
1080+
</dl>
1081+
1082+
The ''view-transition-group-children()'' [=pseudo-element=] is generated
1083+
if and only if there is a ''view-transition-group()'' [=pseudo-element=] attached to it.
1084+
1085+
The [=used value=] for 'view-transition-group' resolves to a 'view-transition-name' in its ancestor chain, or to ''view-transition-name/none''. When generating the [=named view transition pseudo-element=], the ''::view-transition-group()'' with that name
1086+
would create a ''::view-transition-group-children()'' pseudo-element, which would be the parent of the ''::view-transition-group()'' generated for this element's 'view-transition-name'.
1087+
1088+
### Nested View Transition Group Explanation ### {#nested-overview}
1089+
1090+
*This section is non-normative.*
1091+
1092+
By default, setting `view-transition-name` on multiple elements generates a flat [=view transition tree=], where all the ''::view-transition-group()'' pseudo-elements are children of the ''::view-transition'' pseudo-element.
1093+
This is sufficient for many simple use-cases, but there are some styling use-cases that cannot be achieved with a flat tree.
1094+
The most prominent use-case is clipping: with a flat tree, all pseudo-elements are clipped to the [=snapshot containing block=], so clipping elements in the normal tree would lose their clipping during the view-transition, resulting in a broken visual effect.
1095+
The effects that have can have an unexpected visual effect in a flat tree:
1096+
* Clipping ('overflow', 'clip-path', 'border-radius'): clipping affects the children of the element.
1097+
* 'opacity', 'mask-image' and 'filter': These effects that are designed to work on a fully rasterized image of a tree, rather than on each item individually.
1098+
* 3D transforms ('transform-style', 'transform', 'perspective'): to display the full range of 3D transform animations, some hierarchy needs to be kept.
1099+
1100+
To enable these use cases, this specification introduces the concept of nesting view-transition pseudo-elements. By using the 'view-transition-group' CSS property,
1101+
the author can assign a "parent group" for a generated ''::view-transition-group()'' pseudo-element, creating a hierarchy in the [=view transition tree=].
1102+
1103+
### Examples ### {#nested-vt-example}
1104+
1105+
<div class="example">
1106+
This example creates a transition where the [=view transition tree=] is nested instead of flat:
1107+
1108+
```html
1109+
<section class="container">
1110+
<article>Content</article>
1111+
</section>
1112+
```
1113+
1114+
```css
1115+
.container {
1116+
view-transition-name: container;
1117+
}
1118+
1119+
.container,
1120+
::view-transition-group-children(container) {
1121+
clip-path: circle();
1122+
}
1123+
1124+
article {
1125+
view-transition-name: article;
1126+
view-transition-group: container;
1127+
}
1128+
```
1129+
1130+
The pseudo-element tree for this would be as follows:
1131+
```
1132+
::view-transition
1133+
├─ ::view-transition-group(container)
1134+
│ ├─ ::view-transition-image-pair(container)
1135+
│ │ ├─ ::view-transition-old(container)
1136+
│ │ └─ ::view-transition-new(container)
1137+
│ └─ ::view-transition-group-children(container)
1138+
│ ├─ ::view-transition-group(article)
1139+
│ │ ├─ ::view-transition-old(article)
1140+
│ │ └─ ::view-transition-new(article)
1141+
│ └─ ...other nested groups...
1142+
└─ …other groups…
1143+
```
1144+
1145+
By applying the ''clip-path'' to both the containing element and its generated ''::view-transition-group-children()'' pseudo-element, we preserve the clip during the transition,
1146+
and by applying ''view-transition-group'' to the internal element referencing the container, we make the tree "nested" in a way that would apply this clipping.
1147+
</div>
10301148

10311149
# Scoped View Transitions # {#scoped-vt}
10321150

@@ -1121,7 +1239,26 @@ the active view transition of an element is exposed to script via a property on
11211239
This enables full customization of the transition.
11221240
</div>
11231241

1124-
ISSUE: We need an example of view transition nested groups as well.
1242+
<div class=note>
1243+
When using ''view-transition-group'' property,
1244+
an additional ''::view-transition-group-children()'' pseudo is created
1245+
that allows for clipping of descendants and specifying relative transforms.
1246+
1247+
```
1248+
::view-transition
1249+
├─ ::view-transition-group(name)
1250+
│ ├─ ::view-transition-image-pair(name)
1251+
│ │ ├─ ::view-transition-old(name)
1252+
│ │ └─ ::view-transition-new(name)
1253+
│ └─ ::view-transition-group-children(name)
1254+
│ └─ …groups nested under 'name'
1255+
└─ …other groups…
1256+
```
1257+
1258+
''view-transition-group-children()'' element can now be customized to add, for example, clipping with
1259+
'overflow: clip'. This would clip any ''view-transition-group()'' pseudo-elements along with their
1260+
descendants.
1261+
</div>
11251262

11261263
### Named View Transition Pseudo-elements ### {#named-view-transition-pseudo}
11271264

@@ -1247,7 +1384,20 @@ the active view transition of an element is exposed to script via a property on
12471384
Note: The content and [=natural dimensions=] of the image are captured in [=capture the image=],
12481385
then set and updated in [=setup transition pseudo-elements=] and [=update pseudo-element styles=].
12491386

1250-
ISSUE: `::view-transition-group-children()` needs to be specified here.
1387+
### View Transition Group Children: the ''::view-transition-group-children()'' pseudo-element ### {#::view-transition-group-children}
1388+
1389+
The <dfn>::view-transition-group-children()</dfn> [=pseudo-element=]
1390+
is created when mandated by the ''view-transition-group'' property
1391+
on either the element itself or on its contained element.
1392+
It serves as a container for descendant ''view-transition-group()'' pseudo-elements.
1393+
By default, it is sized to the same size as the corresponding ''view-transition-group()'' pseudo element.
1394+
By default, it has a transparent border that matches the size and shape of the border on the element that caused this structure to be created.
1395+
1396+
Note: The size and border setting on this pseudo element allow the developer
1397+
to enable clipping of the descedant pseudo elements with a simple ''overflow:
1398+
clip'' property. The developer needs to take care if the original element has
1399+
non-overscroll scrollbars, since these scrollbars change the clipping area
1400+
from the default provided by this element.
12511401

12521402
# View Transition Layout # {#view-transition-rendering}
12531403

@@ -2090,101 +2240,6 @@ To resolve the [=used value=] of 'view-transition-name' for |element|:
20902240

20912241
A 'view-transition-name' generated by <css>auto</css> is a [=tree-scoped name=].
20922242

2093-
# Nested view-transition groups # {#nested-view-transition-groups}
2094-
2095-
## Overview ## {#nested-overview}
2096-
2097-
*This section is non-normative.*
2098-
2099-
By default, setting `view-transition-name` on multiple elements generates a flat [=view transition tree=], where all the ''::view-transition-group()'' pseudo-elements are children of the ''::view-transition'' pseudo-element.
2100-
This is sufficient for many simple use-cases, but there are some styling use-cases that cannot be achieved with a flat tree.
2101-
The most prominent use-case is clipping: with a flat tree, all pseudo-elements are clipped to the [=snapshot containing block=], so clipping elements in the normal tree would lose their clipping during the view-transition, resulting in a broken visual effect.
2102-
The effects that have can have an unexpected visual effect in a flat tree:
2103-
* Clipping ('overflow', 'clip-path', 'border-radius'): clipping affects the children of the element.
2104-
* 'opacity', 'mask-image' and 'filter': These effects that are designed to work on a fully rasterized image of a tree, rather than on each item individually.
2105-
* 3D transforms ('transform-style', 'transform', 'perspective'): to display the full range of 3D transform animations, some hierarchy needs to be kept.
2106-
2107-
To enable these use cases, this specification introduces the concept of nesting view-transition pseudo-elements. By using the 'view-transition-group' CSS property,
2108-
the author can assign a "parent group" for a generated ''::view-transition-group()'' pseudo-element, creating a hierarchy in the [=view transition tree=].
2109-
2110-
## Examples ## {#nested-vt-example}
2111-
2112-
<div class="example">
2113-
This example creates a transition where the [=view transition tree=] is nested instead of flat:
2114-
2115-
```html
2116-
<section class="container">
2117-
<article>Content</article>
2118-
</section>
2119-
```
2120-
2121-
```css
2122-
.container {
2123-
view-transition-name: container;
2124-
}
2125-
2126-
.container,
2127-
::view-transition-group-children(container) {
2128-
clip-path: circle();
2129-
}
2130-
2131-
article {
2132-
view-transition-name: article;
2133-
view-transition-group: container;
2134-
}
2135-
```
2136-
2137-
The pseudo-element tree for this would be as follows:
2138-
```
2139-
::view-transition
2140-
├─ ::view-transition-group(container)
2141-
│ ├─ ::view-transition-image-pair(container)
2142-
│ | ├─ ::view-transition-old(container)
2143-
│ | └─ ::view-transition-new(container)
2144-
│ └─ ::view-transition-group-children(container)
2145-
│ ├─ ::view-transition-group(article)
2146-
│ | ├─ ::view-transition-old(article)
2147-
│ | └─ ::view-transition-new(article)
2148-
│ └─ ...other nested groups...
2149-
└─ …other groups…
2150-
```
2151-
2152-
By applying the ''clip-path'' to both the containing element and its generated ''::view-transition-group-children()'' pseudo-element, we preserve the clip during the transition,
2153-
and by applying ''view-transition-group'' to the internal element referencing the container, we make the tree "nested" in a way that would apply this clipping.
2154-
</div>
2155-
2156-
## The 'view-transition-group' property ## {#view-transition-group-prop}
2157-
2158-
<pre class=propdef>
2159-
Name: view-transition-group
2160-
Value: normal | contain | nearest | <<custom-ident>>
2161-
Initial: normal
2162-
Inherited: no
2163-
Percentages: n/a
2164-
Computed Value: as specified
2165-
Animation type: discrete
2166-
</pre>
2167-
2168-
The 'view-transition-group' property can be used in conjuction with 'view-transition-name' to generate a hierarchy of [=named view transition pseudo-element=].
2169-
2170-
The [=used value=] for 'view-transition-group' resolves to a 'view-transition-name' in its ancestor chain, or to ''view-transition-name/none''. When generating the [=named view transition pseudo-element=], the ''::view-transition-group()'' with that name
2171-
would create a ''::view-transition-group-children()'' pseudo-element, which would be the parent of the ''::view-transition-group()'' generated for this element's 'view-transition-name'.
2172-
2173-
### View Transition Tree Root: the ''::view-transition-group-children'' pseudo-element ### {#view-transition-group-children-pseudo}
2174-
2175-
The <dfn>::view-transition-group-children()</dfn> [=pseudo-element=]
2176-
is a [=named view transition pseudo-element=]
2177-
that represents a matching named [=view transition=] capture.
2178-
A ''::view-transition-group-children()'' [=pseudo-element=]
2179-
is generated based on the 'view-transition-group' property,
2180-
as a [=tree/child=] of the corresponding ''::view-transition-group()'' [=pseudo-element=],
2181-
and contains one or more ''::view-transition-group()'' elements, corresponding to the nested groups.
2182-
See the [=used group name=] and related algorithms.
2183-
2184-
The ''::view-transition-group-children()'' [=pseudo-element=] is positioned after its sibling ''view-transition-image-pair()''.
2185-
It is used to control effects like clipping or masking of nested children.
2186-
2187-
21882243
# Algorithms # {#algorithms}
21892244

21902245
## Data Structures ## {#concepts}
@@ -2965,19 +3020,10 @@ To resolve the <dfn>used group name</dfn> of an {{Element}} |element|, perform t
29653020
1. Let |containingGroupName| be |element|'s [=nearest containing group name=] given |transition|.
29663021
1. Return the first matching statement, switching on |group|:
29673022

2968-
<dl dfn-type=value dfn-for=view-transition-group>
2969-
: <dfn>normal</dfn>
2970-
: <dfn>contain</dfn>
2971-
:: |containingGroupName|.
2972-
3023+
* ''view-transition-group/normal'', ''view-transition-group/contain'': |containingGroupName|.
29733024
Note: an element with ''view-transition-group/contain'' becomes the [=nearest containing group name=] for its descendants.
2974-
2975-
: <dfn>nearest</dfn>
2976-
:: The [=document-scoped view transition name=] of the element's nearest [=flat tree=] ancestor which participates in the |transition|.
2977-
2978-
: <dfn><<custom-ident>></dfn>
2979-
:: |group| if the element has a [=flat tree=] [=tree/ancestor=] whose [=document-scoped view transition name=] is |group| and participates in |transition|; Otherwise |containingGroupName|.
2980-
</dl>
3025+
* ''view-transition-group/nearest'': The [=document-scoped view transition name=] of the element's nearest [=flat tree=] ancestor which participates in the |transition|.
3026+
* ''view-transition-group/<custom-ident>'': |group| if the element has a [=flat tree=] [=tree/ancestor=] whose [=document-scoped view transition name=] is |group| and participates in |transition|; Otherwise |containingGroupName|.
29813027
</div>
29823028

29833029
#### Compute the old 'view-transition-group' #### {#vt-group-capture-old}
@@ -3489,6 +3535,7 @@ This appendix is <em>informative</em>.
34893535
Changes from <a href="https://www.w3.org/TR/2024/WD-css-view-transitions-2-20240516/">2024-05-16 Working Draft</a>
34903536
</h3>
34913537

3538+
* Add description of nested view transition groups, which was partially missing.
34923539
* Update wording to use `opacity: 0` instead of `visibility: hidden`. See <a href="https://github.com/w3c/csswg-drafts/issues/12629">issue 12629</a>.
34933540
* Replace `contain: view-transition` with `view-transition-scope` property (<a href="https://github.com/w3c/csswg-drafts/issues/13123">pending #13123</a>)
34943541
* Reorder sections, editorial changes, added several issues, updated scoped view transition wording.

0 commit comments

Comments
 (0)