10BC0 [css-view-transitions-2] Initial spec for nested view transitions (#1… · w3c/csswg-drafts@667d3d3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 667d3d3

Browse files
authored
[css-view-transitions-2] Initial spec for nested view transitions (#10629)
1 parent 7dfc13e commit 667d3d3

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

css-view-transitions-2/Overview.bs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@ spec:css-view-transitions-1;
3131
text: update callback done promise; for: ViewTransition; type: dfn;
3232
text: initial snapshot containing block size; for: ViewTransition; type: dfn;
3333
text: captured elements; type: dfn;
34+
text: snapshot containing block; type: dfn;
35+
text: old transform; for: captured element; type: dfn;
36+
text: new element; for: captured element; type: dfn;
3437
text: updateCallbackDone; type: property; for: ViewTransition;
3538
text: phase; type: dfn; for: ViewTransition;
3639
text: call the update callback; type: dfn;
3740
text: perform pending transition operations; type: dfn;
3841
text: setup view transition; type: dfn;
3942
text: named view transition pseudo-element; type: dfn;
4043
text: rendering suppression for view transitions; type: dfn;
44+
text: view transition tree; type: dfn;
45+
text: view transition name; type: dfn;
46+
text: group styles rule; type: dfn;
47+
text: update pseudo-element styles rule; type: dfn;
4148
spec:dom; type:dfn; text:document
4249
spec:css22; type:dfn; text:element
4350
spec:selectors-4; type:dfn;
@@ -51,7 +58,11 @@ spec:html
5158
text: pagereveal; type: dfn; for: Window;
5259
text: has been revealed; type: dfn;
5360
text: render-blocking mechanism; type: dfn;
61+
spec:geometry-1
62+
text:multiply; type:dfn;
63+
text:matrix; type:dfn;
5464
spec:infra; type:dfn; text:list
65+
spec:css-borders-4; type: property; text:border-radius;
5566
</pre>
5667

5768
<style>
@@ -734,6 +745,89 @@ div.box {
734745
1. Return |viewTransition|.
735746
</div>
736747

748+
# Nested view-transitions # {#nested-view-transitions}
749+
750+
## Overview ## {#nested-overview}
751+
752+
*This section is non-normative.*
753+
754+
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.
755+
This is sufficient for many simple use-cases, but there are some styling use-cases that cannot be achieved with a flat tree.
756+
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.
757+
The effects that have can have an unexpected visual effect in a flat tree:
758+
* Clipping ('overflow', 'clip-path', 'border-radius'): clipping affects the children of the element.
759+
* '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.
760+
* 3D transforms ('transform-style', 'transform', 'perspective'): to display the full range of 3D transform animations, some hierarchy needs to be kept.
761+
762+
To enable these use cases, this specification introduces the concept of nesting view-transition pseudo-elements. By using the 'view-transition-group' CSS property,
763+
the author can assign a "parent group" for a generated ''::view-transition-group()'' pseudo-element, creating a hierarchy in the [=view transition tree=].
764+
765+
## Examples ## {#nested-vt-example}
766+
767+
<div class="example">
768+
This example creates a transition where the [=view transition tree=] is nested instead of flat:
769+
770+
```html
771+
<section class="container">
772+
<article>Content</article>
773+
</section>
774+
```
775+
776+
```css
777+
.container {
778+
view-transition-name: container;
779+
}
780+
781+
.container,
782+
::view-transition-group(container) {
783+
clip-path: circle();
784+
}
785+
786+
article {
787+
view-transition-name: article;
788+
view-transition-group: container;
789+
}
790+
```
791+
792+
By applying the ''clip-path'' to both the containing element and its generated pseudo-element, we preserve the clip during the transition,
793+
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.
794+
</main>
795+
796+
## The 'view-transition-group' property ## {#view-transition-group-prop}
797+
798+
<pre class=propdef>
799+
Name: view-transition-group
800+
Value: normal | contain | nearest | <<custom-ident>>
801+
Initial: normal
802+
Inherited: no
803+
Percentages: n/a
804+
Computed Value: as specified
805+
Animation type: discrete
806+
</pre>
807+
808+
The 'view-transition-group' property can be used in conjuction with 'view-transition-name' to generate a hierarchy of [=named view transition pseudo-element=].
809+
810+
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
811+
would be the parent of the ''::view-transition-group()'' generated for this element's 'view-transition-name'.
812+
813+
When the [=computed value=] of 'view-transition-name' for an element is ''view-transition-name/none'', its 'view-transition-group' [=used value=] is always resolved to ''view-transition-name/none'' as well.
814+
815+
<dl dfn-type=value dfn-for=view-transition-group>
816+
: <dfn>normal</dfn>
817+
:: The [=used value=] is the element's [=nearest containing group name=].
818+
819+
: <dfn>nearest</dfn>
820+
:: The [=used value=] is the 'view-transition-name' [=computed value=] of the nearest ancestor whose 'view-transition-name' [=computed value=] is not ''view-transition-name/none''.
821+
822+
: <dfn>contain</dfn>
823+
:: The [=used value=] is the element's [=nearest containing group name=].
824+
825+
Note: Descendant elements are contained within this group by default, as it would be their element's [=nearest containing group name=].
826+
827+
: <dfn><<custom-ident>></dfn>
828+
:: The [=used value=] is the given <<custom-ident>> if the element has an ancestor whose 'view-transition-name' [=computed value=] is that <<custom-ident>>, otherwise the element's [=nearest containing group name=]
829+
</dl>
830+
737831
# Algorithms # {#algorithms}
738832

739833
## Data structures ## {#cross-doc-data-structures}
@@ -780,6 +874,12 @@ The [=captured element=] struct should contain these fields, in addition to the
780874
<dl>
781875
: <dfn for="captured element">class list</dfn>
782876
:: a [=/list=] of strings, initially empty.
877+
878+
: <dfn for="captured element">containing group name</dfn>
879+
:: Null or a string, initially null.
880+
881+
: <dfn for="captured element">transform from snapshot containing block</dfn>
882+
:: A [=matrix=], initially the identity matrix.
783883
</dl>
784884

785885
## Resolving the ''@view-transition'' rule ## {#vt-rule-algo}
@@ -985,6 +1085,67 @@ When capturing the old or new state for an element, perform the following steps
9851085
Note: This is written in a monkey-patch manner, and will be merged into the algorithm once the L1 spec graduates.
9861086
</div>
9871087

1088+
## Capturing and applying 'view-transition-group' ## {#vt-group-algorithm}
1089+
1090+
### Compute the nearest containing 'view-transition-group' ### {#vt-group-nearest-contain}
1091+
<div algorithm="nearest containing group name">
1092+
1093+
To get the <dfn>nearest containing group name</dfn> for an {{Element}} |element|, perform the following steps:
1094+
1095+
1. Let |nearestAncestorWithContain| be |element|'s nearest ancestor whose 'view-transition-name' [=computed value=] is not ''view-transition-name/none'' and whose 'view-transition-group' [=computed value=] is ''view-transition-group/contain''.
1096+
1. If |nearestAncestorWithContain| is null, return ''view-transition-group/none''.
1097+
1. Otherwise, return |nearestAncestorWithContain|'s 'view-transition-name' [=computed value=].
1098+
</div>
1099+
1100+
### Compute the old 'view-transition-group' ### {#vt-group-capture-old}
1101+
<div algorithm="additional old capture steps (group)">
1102+
When [[css-view-transitions-1#capture-old-state-algorithm|capturing the old state for an element]], perform the following steps given a [=captured element=] |capturedElement|, and an [=element=] |element|:
1103+
1104+
1. Set |capturedElement|'s [=captured element/containing group name=] to the [=used value=] of |element|'s ''view-transition-group''.
1105+
</div>
1106+
1107+
### Compute the new 'view-transition-group' ### {#vt-group-capture-new}
1108+
<div algorithm="additional new capture steps (group)">
1109+
When [[css-view-transitions-1#capture-new-state-algorithm|capturing the new state for an element]], perform the following steps given a [=captured element=] |capturedElement| and an [=element=] |element|:
1110+
1111+
1. Set |capturedElement|'s [=captured element/containing group name=] to the [=used value=] of |element|'s 'view-transition-group'.
1112+
</div>
1113+
1114+
### Reparent a ''::view-transition-group()'' to its specified containing group ### {#vt-group-reparent}
1115+
<div algorithm="additional pseudo-element setup steps (group)">
1116+
When [[css-view-transitions-1#setup-transition-pseudo-elements-algorithm|setting up the transition pseudo-element]] for a [=captured element=] |capturedElement|, given a |transitionName| and a |transition|:
1117+
1118+
1. Let |containingGroupName| be |capturedElement|'s [=containing group name=].
1119+
1. If |containingGroupName| is not null, then:
1120+
1121+
1. Let |groupContainerElement| be |transition|'s [=ViewTransition/named elements=][|containingGroupName|].
1122+
1123+
1. Let |group| be the ''::view-transition-group()'',
1124+
whose [=view transition name=] is set to |transitionName|.
1125+
1126+
1. Let |parentGroup| be the ''::view-transition-group()'',
1127+
whose [=view transition name=] is set to |containingGroupName|.
1128+
1129+
1. Append |group| to |parentGroup|.
1130+
1131+
1. When setting the animation keyframes given |transform|, [=multiply=] |transform| by the inverse matrix of |groupContainerElement|'s [=old transform=].
1132+
1133+
Note: It is TBD how this is resolved when the old and new groups mismatch. See <a href="https://github.com/w3c/csswg-drafts/issues/10631">Issue 10631</a>.
1134+
</div>
1135+
1136+
### Adjust the group's 'transform' to be relative to its containing ''::view-transition-group()'' ### {#vt-group-transform-adjust}
1137+
<div algorithm="additional pseudo-element style update steps (group)">
1138+
When [[css-view-transitions-1#style-transition-pseudo-elements-algorithm|updating the style of the transition pseudo-element]], perform the following steps before setting the [=captured element/group styles rule=], given a [=captured element=] |capturedElement|, given a |transform| and a {{ViewTransition}} |transition|:
1139+
1140+
1. Set |capturedElement|'s [=transform from snapshot containing block=] to |transform|.
1141+
1142+
1. If |capturedElement|'s [=containing group name=] is not null, then:
1143+
1144+
1. Let |groupContainerElement| be |transition|'s [=ViewTransition/named elements=][|capturedElement|'s [=containing group name=]].
1145+
1146+
1. [=Multiply=] |transform| by the inverse matrix of |groupContainerElement|'s [=transform from snapshot containing block=].
1147+
</div>
1148+
9881149
<h2 id="priv" class="no-num">Privacy Considerations</h2>
9891150

9901151
This specification introduces no new privacy considerations.

0 commit comments

Comments
 (0)
0