You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Shared element transitions is a set of API that allow DOM changes to smoothly
46
+
animate between states. This is accomplished by leveraging user-agents ability
47
+
to persist visual representations of state (i.e. snapshots) and blend them with
48
+
current DOM state's visual output. The API also allows the animations to be
49
+
customized via standard CSS animation properties.
50
+
43
51
This spec describes the CSS and JS mechanics of the single-page transition API.
44
52
45
53
# Transitions as an enhancement # {#transitions-as-enhancements}
46
54
47
55
<em>This section is non-normative.</em>
48
56
49
-
A key part of this API design is the view that an animated transition is an enhancement to a DOM change.
50
-
51
-
If a transition cannot run, or is skipped, the DOM change should still happen. If the DOM change should also be skipped, then that should be handled by another feature. The <a href="https://wicg.github.io/navigation-api/#navigate-event-class">`signal` on `NavigateEvent`</a> is an example of a feature developers could use to handle this.
52
-
53
-
Although the transition API allows DOM changes to be asynchronous via the {{DOMTransitionInit/updateDOM}} callback, the transition API is not responsible for queuing or otherwise scheduling the DOM changes, beyond the scheduling needed for the transition itself. Some asynchronous DOM changes can happen concurrently (e.g if they're happening within independent components), whereas others need to queue, or abort an earlier change. This is best left to a feature or framework that has a more holistic view of the update.
57
+
A key part of this API design is the view that an animated transition is an
58
+
enhancement to a DOM change. Specifically, there are two components of the API:
59
+
the DOM change, and the visual state animation.
60
+
61
+
In order for the user-agent to generate a set of snapshots prior to the DOM
62
+
change, the API is designed to take the DOM change callback as part of the
63
+
request to initiate a transition. This means that the user-agent has an
64
+
opportunity to generate snapshots for the existing visual representation, run
65
+
the given callback to update the state, and finally generate structures and set
66
+
up animations required for the transition to occur. All this is accomplished
67
+
with a single call to the JavaScript API.
68
+
69
+
The user-agent provides additional JavaScript functionality and promises to
70
+
control and observe the state of the animations. These are described in detail
71
+
in the {{DOMTransition}} section.
72
+
73
+
After the callback has finished running, the user-agent creates a structure of
74
+
pseudo-elements that represent both the "before" and "after" states of the
75
+
transition. The structure of the pseudo-elements is dictated by the
76
+
''page-transition-tag'' property. Specifically, each element that is "tagged"
77
+
with a ''page-transition-tag'' creates a separate snapshot and thus a separate
78
+
group of pseudo-elements that are animated independently from the rest. Note
79
+
that for convenience, the root element is tagged with name "root" in the
80
+
user-agent style sheet.
81
+
82
+
The groups induced by the ''page-transition-tag'' are all positioned within a
83
+
common pseudo-element root, which itself is attached to the root element of the
84
+
page.
85
+
86
+
Each of the groups is comprised of up to four pseudo elements:
87
+
* Container pseudo-element: this element initially mirrors the size and
88
+
position of the "before" state element that it represents (i.e. the tagged
89
+
element that caused this group to be created). The element is animated to
90
+
the "after" state and position.
91
+
* Wrapper pseudo-element: this element is a child of the container element and
92
+
provides ''isolation: isolate'' for its children. It's needed so that its
93
+
children can be blended with non-normal blend modes without affecting other
94
+
visual outputs.
95
+
* Outgoing image: this element is a child of the wrapper element. It is a
96
+
replaced element that produced the visual representation of the "before"
97
+
state taken from user-agent provided snapshots. Note that the contents of
98
+
this element can be manipulated with ''object-*'' properties in the same way
99
+
that other replaced elements can be.
100
+
* Incoming image: this element is a child of the wrapper element. It is a
101
+
replaced element that produces the visual representation of the "after"
102
+
state, taken from the page's visual output of the represented elements. Like
103
+
outgoing image, the contents can be manipulated with ''object-*'' properties.
104
+
Note that because this element's snapshots are taken from the pages output,
105
+
the visual output changes if the visual output of the represented element
on `NavigateEvent`</a> is an example of a feature developers could use to
122
+
handle this.
123
+
* Although the transition API allows DOM changes to be asynchronous via the
124
+
{{DOMTransitionInit/updateDOM}} callback, the transition API is not
125
+
responsible for queuing or otherwise scheduling the DOM changes, beyond the
126
+
scheduling needed for the transition itself. Some asynchronous DOM changes
127
+
can happen concurrently (e.g if they're happening within independent
128
+
components), whereas others need to queue, or abort an earlier change. This
129
+
is best left to a feature or framework that has a more holistic view of the
130
+
update.
54
131
55
132
# CSS properties # {#css-properties}
56
133
@@ -92,6 +169,17 @@ the following style in the [=user-agent origin=].
92
169
}
93
170
</code></pre>
94
171
172
+
<div class=note>This property causes the user-agent to both capture separate
173
+
snapshots from the elements, as well as create separate pseudo-element
174
+
sub-trees representing this element's "before" and "after" states. Note that
175
+
for the purposes of this API, if one element has a tag "foo" in the before
176
+
state, and another element has a tag "foo" in the after state, they are treated
177
+
as representing different visual state of the same element. This may be
178
+
confusing, since the elements themselves are not necessarily referring to the
179
+
same object, but it is a useful model to consider them to be visual states of
180
+
the same conceptual page entity, that we happen to call element.
181
+
</div>
182
+
95
183
# Pseudo-elements # {#pseudo}
96
184
97
185
While the UA is [=animating a page transition=],
@@ -129,7 +217,8 @@ the same <<custom-ident>> value. The specificity of a page-transition selector
129
217
with a <<custom-ident>> argument is the same as for other pseudo-elements, and
130
218
is equivalent to a [=type selector=].
131
219
132
-
The following describes all of the [=page-transition pseudo-elements=] and their function:
220
+
The following describes all of the [=page-transition pseudo-elements=] and
221
+
their function:
133
222
134
223
: <dfn>::page-transition</dfn>
135
224
:: This pseudo-element is the grouping container of all the other
@@ -271,10 +360,22 @@ algorithm.
271
360
272
361
## Phases ## {#phases-concept}
273
362
274
-
<dfn>Phases</dfn> represent an ordered sequence of states. Since [=phases=] are ordered, prose can refer to phases <dfn for="phases">before</dfn> a particular phase, meaning they appear earlier in the sequence, or <dfn for="phases">after</dfn> a particular phase, meaning they appear later in the sequence.
363
+
<dfn>Phases</dfn> represent an ordered sequence of states. Since [=phases=] are
364
+
ordered, prose can refer to phases <dfn for="phases">before</dfn> a particular
365
+
phase, meaning they appear earlier in the sequence, or <dfn
366
+
for="phases">after</dfn> a particular phase, meaning they appear later in the
367
+
sequence.
275
368
276
369
The initial phase is the first item in the sequence.
277
370
371
+
Note: For the most part, a developer using this API does not need to worry
372
+
about the different phases, since they progress automatically. It is, however,
373
+
important to understand what steps happen in each of the phases: when the
374
+
snapshots are captured, when pseudo-element DOM is created, etc. The
375
+
description of the phases below tries to be as precise as possible, with an
376
+
intent to provide an unambiguous set of steps for implementors to follow in
377
+
order to produce a spec-compliant implementation.
378
+
278
379
## The [=page-transition layer=] stacking layer ## {#page-transition-stacking-layer}
279
380
280
381
This specification introduces a stacking layer to the
1. If |document|'s [=active DOM transition=] is not null, then [=skip the page transition=] |document|'s [=active DOM transition=]
372
473
with an "{{AbortError}}" {{DOMException}} in [=this's=][=relevant Realm=].
373
474
374
-
Note: This can result in two asynchronous [=DOMTransition/DOM update callbacks=] running concurrently. One for the |document|'s current [=active DOM transition=], and another for this |transition|. As per the [design of this feature](#transitions-as-enhancements), it's assumed that the developer is using another feature or framework to correctly schedule these DOM changes.
475
+
Note: This can result in two asynchronous [=DOMTransition/DOM update
476
+
callbacks=] running concurrently. One for the |document|'s current
477
+
[=active DOM transition=], and another for this |transition|. As per
478
+
the [design of this feature](#transitions-as-enhancements), it's
479
+
assumed that the developer is using another feature or framework to
480
+
correctly schedule these DOM changes.
375
481
376
482
1. Set |document|'s [=active DOM transition=] to |transition|.
0 commit comments