Skip to content
98 changes: 62 additions & 36 deletions css-view-transitions-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Shortname: css-view-transitions
Level: 1
Status: WD
Group: csswg
Date: 2023-03-07
Date: 2023-04-18
Prepare for TR: yes
ED: https://drafts.csswg.org/css-view-transitions-1/
TR: https://www.w3.org/TR/css-view-transitions-1/
Expand Down Expand Up @@ -32,6 +32,7 @@ spec:css-display-3; type:dfn;
text:containing block
text:replaced element
spec:css-cascade-5; type:dfn; text:computed value
spec:css22; type:dfn; text:element
</pre>

<pre class=anchors>
Expand Down Expand Up @@ -479,11 +480,11 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

<dl dfn-type=value dfn-for=view-transition-name>
: <dfn>none</dfn>
:: The element will not participate in a view transition.
:: The [=/element=] will not participate in a view transition.

: <dfn><<custom-ident>></dfn>
:: The element can participate in a view transition,
as either an old or new element,
:: The [=/element=] can participate in a view transition,
as either an old or new [=/element=],
with a <dfn dfn for>view transition name</dfn> equal to the <<custom-ident>>'s value.

Note: The value <css>none</css> is invalid as a <<custom-ident>>.
Expand All @@ -497,6 +498,21 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
This may be confusing, since the elements themselves are not necessarily referring to the same object,
but it is a useful model to consider them to be visual states of the same conceptual page entity, that we happen to call "element".

# Layout and rendering changes # {#layout-rendering-changes}

[=/Elements=] have an <dfn>involved in a view transition</dfn> boolean, initially false.

[=/Elements=] that either have a 'view-transition-name' [=computed value=] that is not ''view-transition-name/none'',
or are [=involved in a view transition=], form:

- a [=stacking context=].

- a [[css-transforms-2#grouping-property-values|group]].

- a [=backdrop root=].

Note: This spec uses CSS's definition of [=element=], which includes [=pseudo-elements=].

# User-agent styles # {#ua-styles}

The <dfn>global view transition user agent style sheet</dfn> is a style sheet in the [=user-agent origin=], used in all namespaces.
Expand Down Expand Up @@ -593,7 +609,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
This enables full customization of the transition.
</div>

### <dfn>::view-transition</dfn>
### <dfn>::view-transition</dfn> ### {#::view-transition}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just fixing some bikeshed errors while I'm here


<div class=note>This element provides a containing block for all ''::view-transition-group()'' pseudo-elements.</div>

Expand All @@ -617,7 +633,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
and position all ''::view-transition-group()'' pseudo-elements relative to the [=snapshot root origin=].
</div>

### <dfn>::view-transition-group( <<pt-name-selector>> )</dfn>
### <dfn>::view-transition-group( <<pt-name-selector>> )</dfn> ### {#::view-transition-group}

<div class=note>
This element initially mirrors the size and position of the "old" element,
Expand Down Expand Up @@ -652,7 +668,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
}
```

### <dfn>::view-transition-image-pair( <<pt-name-selector>> )</dfn>
### <dfn>::view-transition-image-pair( <<pt-name-selector>> )</dfn> ### {#::view-transition-image-pair}

<div class=note>
This element is a child of the group element and provides ''isolation: isolate'' for its children.
Expand All @@ -679,7 +695,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
}
```

### <dfn>::view-transition-old( <<pt-name-selector>> )</dfn>
### <dfn>::view-transition-old( <<pt-name-selector>> )</dfn> ### {#::view-transition-old}

<div class=note>

Expand Down Expand Up @@ -726,7 +742,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

Note: Additional styles in the [=document/view transition style sheet=] added to animate these pseudo-elements are detailed in [=setup transition pseudo-elements=] and [=update pseudo-element styles=].

### <dfn>::view-transition-new( <<pt-name-selector>> )</dfn>
### <dfn>::view-transition-new( <<pt-name-selector>> )</dfn> ### {#::view-transition-new}

Identical to ''::view-transition-old()'',
except the following styles added to the [=global view transition user agent style sheet=]:
Expand Down Expand Up @@ -828,9 +844,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
Issue: The type of "a set of styles" needs to be linked or defined.

: <dfn>new element</dfn>
:: an element or null. Initially null.

Issue: The type of "element" needs to be linked or defined.
:: an [=/element=] or null. Initially null.
</dl>

In addition, a [=captured element=] has the following <dfn for="captured element">style definitions</dfn>:
Expand Down Expand Up @@ -1175,10 +1189,18 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
If failure is returned, then [=skip the view transition=] for |transition| with an "{{InvalidStateError}}" {{DOMException}} in |transition|'s [=relevant Realm=],
and return.

1. [=list/For each=] |capturedElement| of |transition|'s [=ViewTransition/named elements=]' [=map/values=]:

1. If |capturedElement|'s [=captured element/new element=] is not null,
then set |capturedElement|'s [=captured element/new element=]'s [=involved in a view transition=] to true.

1. [=Setup transition pseudo-elements=] for |transition|.

1. [=Update pseudo-element styles=] for |transition|.

If failure is returned, then [=skip the view transition=] for |transition| with an "{{InvalidStateError}}" {{DOMException}} in |transition|'s [=relevant Realm=],
and return.

Note: The above steps will require running document lifecycle phases,
to compute information calculated during style/layout.

Expand All @@ -1202,7 +1224,8 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. Set |transition|'s [=ViewTransition/initial snapshot root size=] to the [=snapshot root size=].

1. [=list/For each=] |element| of every {{Element}} and [=pseudo-element=] connected to |document|,
1. [=list/For each=] |element| of every [=/element=] that is [=/connected=],
and has a [=node document=] equal to to |document|,
in [paint order](https://drafts.csswg.org/css2/#painting-order):

Issue: The link for "paint order" doesn't seem right.
Expand All @@ -1220,8 +1243,6 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

* |usedTransitionNames| [=list/contains=] |transitionName|.

* |element| is not |element|'s [=tree/root=] and |element| does not have [=layout containment=].

* |element| is not |element|'s [=tree/root=] and |element| allows [=fragmentation=].

Then return failure.
Expand Down Expand Up @@ -1268,9 +1289,12 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. Let |document| be |transition|'s [=relevant global object's=] [=associated document=].

1. Let |namedElements| be |transition|'s [=ViewTransition/named elements=].

Comment on lines +1292 to +1293
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick fix of something that was missed in an earlier refactor

1. Let |usedTransitionNames| be a new [=/set=] of strings.

1. [=list/For each=] |element| of every {{Element}} and [=pseudo-element=] connected to |document|,
1. [=list/For each=] |element| of every [=/element=] that is [=/connected=],
and has a [=node document=] equal to to |document|,
in [paint order](https://drafts.csswg.org/css2/#painting-order):

Issue: The link for "paint order" doesn't seem right.
Expand All @@ -1284,26 +1308,15 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
or |element| is [=element-not-rendered|not rendered=],
then [=continue=].

1. If any of the following is true:

* |usedTransitionNames| [=list/contains=] |transitionName|.

* |element| is not |element|'s [=tree/root=]
and |element| does not have [=layout containment=].

* |element| is not |element|'s [=tree/root=]
and |element| allows [=fragmentation=].

Then return failure.
1. If |usedTransitionNames| [=list/contains=] |transitionName|,
then return failure.

1. [=set/Append=] |transitionName| to |usedTransitionNames|.

1. If |namedElements|[|transitionName|] does not [=map/exist=],
then set |namedElements|[|transitionName|] to a new [=captured element=] struct.

1. Let |capture| be |namedElements|[|transitionName|].

1. Let |capture|'s [=new element=] item be |element|.
1. Set |namedElements|[|transitionName|]'s [=new element=] to |element|.
</div>

### [=Setup transition pseudo-elements=] ### {#setup-transition-pseudo-elements-algorithm}
Expand Down Expand Up @@ -1356,8 +1369,9 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
1. If |capturedElement|'s [=new element=] is not null, then:

1. Let |new| be a new ''::view-transition-new()'',
with its [=named view-transition pseudo-element/view-transition name=] set to |transitionName|,
displaying the [=capture the image=] of |capturedElement|'s [=new element=].
with its [=named view-transition pseudo-element/view-transition name=] set to |transitionName|.

Note: The styling of this pseudo is handled in [=update pseudo-element styles=].

1. Append |new| to |imagePair|.

Expand Down Expand Up @@ -1502,7 +1516,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;
## [=Capture the image=] ## {#capture-the-image-algorithm}

<div algorithm>
To <dfn lt="capture the image|capturing the image">capture the image</dfn> given an {{Element}} |element|, perform the following steps.
To <dfn lt="capture the image|capturing the image">capture the image</dfn> given an [=/element=] |element|, perform the following steps.
They return an image.

1. If |element| is the [=document element=], then:
Expand Down Expand Up @@ -1636,6 +1650,9 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. [=Update pseudo-element styles=] for |transition|.

If failure is returned, then [=skip the view transition=] for |transition| with an "{{InvalidStateError}}" {{DOMException}} in |transition|'s [=relevant Realm=],
and return.

Note: The above implies that a change in incoming element's size or position will cause a new keyframe to be generated.
This can cause a visual jump.
We could retarget smoothly but don't have a use-case to justify the complexity.
Expand Down Expand Up @@ -1665,6 +1682,12 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. Otherwise:

1. If any [=flat tree=] ancestor of |capturedElement|'s [=new element=] [=skips its contents=],
or |capturedElement|'s [=new element=] is [=element-not-rendered|not rendered=],
then return failure.

Note: Other rendering constraints are enforced via |capturedElement|'s [=new element=] being [=involved in a view transition=].

1. Set |width| to the current width of |capturedElement|'s [=new element=]'s [=border box=].

1. Set |height| to the current height of |capturedElement|'s [=new element=]'s [=border box=].
Expand Down Expand Up @@ -1696,9 +1719,9 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. If |capturedElement|'s [=new element=] is not null, then:

1. Let |new| be the ''::view-transition-new()'' [=replaced element=] pseudo-element,
with the name |transitionName|,
displaying the [=capture the image=] of |capturedElement|'s [=new element=].
1. Let |new| be the ''::view-transition-new()'' with the [=view-transition name=] |transitionName|.

1. Set |new|'s [=replaced element=] content to the result of [=capturing the image=] of |capturedElement|'s [=new element=].

1. Let |newViewBox| be an ''object-view-box'' value that when applied to |new|,
will cause the view box to coincide with |capturedElement|'s [=new element=]'s [=border box=] in the image.
Expand Down Expand Up @@ -1735,6 +1758,9 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

1. [=list/For each=] |capturedElement| of |transition|'s [=ViewTransition/named elements=]' [=map/values=]:

1. If |capturedElement|'s [=captured element/new element=] is not null,
then set |capturedElement|'s [=captured element/new element=]'s [=involved in a view transition=] to false.

1. [=list/For each=] |style| of |capturedElement|'s [=captured element/style definitions=]:

1. If |style| is not null,
Expand Down