Skip to content

Commit

Permalink
[css-view-transitions-1] Handling rendering constaints (#8540)
Browse files Browse the repository at this point in the history
* Layout impact of view-transition-name

Fixes #8139

* Handle cases where constraints are broken mid-transition

Fixes #7882

---------

Co-authored-by: Tab Atkins Jr. <jackalmage@gmail.com>
  • Loading branch information
jakearchibald and tabatkins authored Apr 19, 2023
1 parent da4695a commit d74719a
Showing 1 changed file with 62 additions and 36 deletions.
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}

<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=].

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

0 comments on commit d74719a

Please sign in to comment.