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 regular images 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
106
+
changes. This is similar to how an 'element()' function would work.
107
+
108
+
ISSUE: This sections can benefit from diagrams.
109
+
110
+
Each of the pseudo-elements generated can be targeted by CSS in order to
111
+
customize its appearance and behavior. This enables full customization of the
112
+
transition.
113
+
114
+
Note that because these APIs are an enhancement to the DOM change, some principles emerge:
115
+
* If a transition cannot run, or is skipped, the DOM change should still
116
+
happen. If the DOM change should also be skipped, then that should be handled
on `NavigateEvent`</a> is an example of a feature developers could use to
120
+
handle this.
121
+
* Although the transition API allows DOM changes to be asynchronous via the
122
+
{{DOMTransitionInit/updateDOM}} callback, the transition API is not
123
+
responsible for queuing or otherwise scheduling the DOM changes, beyond the
124
+
scheduling needed for the transition itself. Some asynchronous DOM changes
125
+
can happen concurrently (e.g if they're happening within independent
126
+
components), whereas others need to queue, or abort an earlier change. This
127
+
is best left to a feature or framework that has a more holistic view of the
128
+
update.
54
129
55
130
# CSS properties # {#css-properties}
56
131
@@ -92,6 +167,17 @@ the following style in the [=user-agent origin=].
92
167
}
93
168
</code></pre>
94
169
170
+
<div class=note>This property causes the user-agent to both capture separate
171
+
snapshots from the elements, as well as create separate pseudo-element
172
+
structure representing this element's "before" and "after" states. Note that
173
+
for the purposes of this API, if one element has a tag "foo" in the before
174
+
state, and another element has a tag "foo" in the after state, they are treated
175
+
as representing different visual state of the same element. This may be
176
+
confusing, since the elements themselves are not necessarily referring to the
177
+
same object, but it is a useful model to consider them to be visual states of
178
+
the same conceptual page entity, that we happen to call element.
179
+
</div>
180
+
95
181
# Pseudo-elements # {#pseudo}
96
182
97
183
While the UA is [=animating a page transition=],
@@ -129,7 +215,8 @@ the same <<custom-ident>> value. The specificity of a page-transition selector
129
215
with a <<custom-ident>> argument is the same as for other pseudo-elements, and
130
216
is equivalent to a [=type selector=].
131
217
132
-
The following describes all of the [=page-transition pseudo-elements=] and their function:
218
+
The following describes all of the [=page-transition pseudo-elements=] and
219
+
their function:
133
220
134
221
: <dfn>::page-transition</dfn>
135
222
:: This pseudo-element is the grouping container of all the other
@@ -271,10 +358,22 @@ algorithm.
271
358
272
359
## Phases ## {#phases-concept}
273
360
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.
361
+
<dfn>Phases</dfn> represent an ordered sequence of states. Since [=phases=] are
362
+
ordered, prose can refer to phases <dfn for="phases">before</dfn> a particular
363
+
phase, meaning they appear earlier in the sequence, or <dfn
364
+
for="phases">after</dfn> a particular phase, meaning they appear later in the
365
+
sequence.
275
366
276
367
The initial phase is the first item in the sequence.
277
368
369
+
Note: For the most part, a developer using this API does not need to worry
370
+
about the different phases, since they progress automatically. It is, however,
371
+
important to understand what steps happen in each of the phases: when the
372
+
snapshots are captured, when pseudo-element DOM is created, etc. The
373
+
description of the phases below tries to be as precise as possible, with an
374
+
intent to provide an unambiguous set of steps for implementors to follow in
375
+
order to produce a spec-compliant implementation.
376
+
278
377
## The [=page-transition layer=] stacking layer ## {#page-transition-stacking-layer}
279
378
280
379
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
471
with an "{{AbortError}}" {{DOMException}} in [=this's=][=relevant Realm=].
373
472
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.
473
+
Note: This can result in two asynchronous [=DOMTransition/DOM update
474
+
callbacks=] running concurrently. One for the |document|'s current
475
+
[=active DOM transition=], and another for this |transition|. As per
476
+
the [design of this feature](#transitions-as-enhancements), it's
477
+
assumed that the developer is using another feature or framework to
478
+
correctly schedule these DOM changes.
375
479
376
480
1. Set |document|'s [=active DOM transition=] to |transition|.
0 commit comments