Skip to content
Next Next commit
[css-view-transitions-2] Add 'view-transition-class'
A `view-transition-class` property allows specifying view-transition pseudo-elements
that apply to multiple participating elements without having to replicate them.

In this PR:
- Specifying `view-transition-class`
- Extending the pseudo-element syntax to support `::view-transition-foo(name.class)`
- Extending the capture algorithms and data structure to capture the classes
- Added a simple example for using classes

Based on [this resolution](#8319 (comment)).
Closes #8319
  • Loading branch information
noamr committed Jan 25, 2024
commit d49b54adfdcda414d308096a8e067ea7cc9caeaf
2 changes: 1 addition & 1 deletion css-view-transitions-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1168,7 +1168,7 @@ urlPrefix: https://wicg.github.io/navigation-api/; type: interface;

### [=Captured elements=] ### {#captured-elements}

A <dfn>captured element</dfn> is a [=struct=] with the following:
A <dfn export>captured element</dfn> is a [=struct=] with the following:

<dl dfn-for="captured element">
: <dfn>old image</dfn>
Expand Down
129 changes: 129 additions & 0 deletions css-view-transitions-2/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ spec:css-view-transitions-1;
text: setup view transition; type: dfn;
spec:dom; type:dfn; text:document
spec:css22; type:dfn; text:element
spec:selectors-4; type:dfn;
text:selector
text:type selector
spec:html
text: latest entry; type: dfn;
text: was created via cross-origin redirects; type: dfn;
Expand Down Expand Up @@ -199,6 +202,83 @@ spec:infra; type:dfn; text:list
```
</div>

### Example of using 'view-transition-class' ### {#vt-class-example}
Copy link
Member

Choose a reason for hiding this comment

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

Mind adding a similar sub-heading above for "cross-document view transitions".


In addition to cross-document view-transitions, this document specifies a way to use the same view-transition style
for multiple elements without having to replicate the corresponding pseudo-elements.

<div class="example">
This example creates a transition with each box participating under its own name, while applying
a 1-second duration to the animation of all the boxes:

```html
<div class="box" id="red-box"></div>
<div class="box" id="green-box"></div>
<div class="box" id="yellow-box"></div>
```

```css
div.box {
view-transition-class: any-box;
width: 100px;
height: 100px;
}
#red-box {
view-transition-name: red-box;
background: red;
}
#green-box {
view-transition-name: green-box;
background: green;
}
#yellow-box {
view-transition-name: yellow-box;
background: yellow;
}

/* The following style would apply to all the boxes, thanks to 'view-transition-class' */
::view-transition-group(*.any-box) {
animation-duration: 1s;
}
```

</div>


# CSS Properties # {#css-properties}

## Applying the same style to multiple participating elements: the 'view-transition-class' property ## {#view-transition-class-prop}

<pre class=propdef>
Name: view-transition-class
Value: none | <<custom-ident>>*
Initial: none
Inherited: no
Percentages: n/a
Computed Value: as specified
Animation type: discrete
</pre>

The 'view-transition-class' works alongside 'view-transition-name', and is read at the same time
Copy link
Member

Choose a reason for hiding this comment

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

I felt that this block had a few redundant statements. A suggestion to reword, lmk what you think:

The 'view-transition-class' can be used to apply the same style rule to multiple [=named view transition pseudo-elements=] which may have a different [=view-transition-name=].

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

'view-transition-name' is read. But unlike 'view-transition-name', 'view-transition-class' doesn't
have to be unique - an element can have several view-transition classes, and the same 'view-transition-class'
can apply to multiple elements. While 'view-transition-name' is used to match between the element
in the old state with its corresponding element in the new state, 'view-transition-class' is used
Copy link
Member

Choose a reason for hiding this comment

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

I'd add a sentence to say explicitly that view-transition-class on its own does not affect the structure of the view transition pseudo element tree constructed.

I know this is what this says, but perhaps repeating in a different way is worthwhile even if non-normatively

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

only to apply styles using the view-transition pseudo-elements
(''::view-transition-group()'', ''::view-transition-image-pair()'', ''::view-transition-old()'', ''::view-transition-new()'').

<dl dfn-type=value dfn-for=view-transition-class>
: <dfn>none</dfn>
:: No class would apply to the [=/element=], and pseudo-elements would have to match its 'view-transition-name'.

: <dfn><<custom-ident>>*</dfn>
:: All of the specified <<custom-ident>> values (apart from <css>none</css>) apply as classes for the [=/element=].
Copy link
Member

Choose a reason for hiding this comment

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

Are we excluding auto here as well?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should... I don't see how class being auto would be a useful reserved keyword since the class doesn't affect anything we do, just allow more selection

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
:: All of the specified <<custom-ident>> values (apart from <css>none</css>) apply as classes for the [=/element=].
:: All of the specified <<custom-ident>> values (apart from <css>none</css>) are applied to the [=named view-transition pseudo-elements=] generated for this element.
Copy link
Member

Choose a reason for hiding this comment

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

This needs to be defined a bit better I think, using [=captured element/class list=] perhaps, or reference the algorithm below.


Note: If the same 'view-transition-name' is specified for an element both in the old and new states of the transition,
only the 'view-transition-class' values from the new state apply. This also applies for cross-document view-transitions:
classes from the old document would only apply if their corresponding 'view-transition-name' was not specified in the new document.
</dl>

# Pseudo-classes # {#pseudo-classes}

## Active View Transition Pseudo-class '':active-view-transition()''' ## {#the-active-view-transition-pseudo}
Expand Down Expand Up @@ -252,6 +332,34 @@ document.startViewTransition({update: updateTheDOMSomehow});
```
</div>

# Additions to view-transition pseudo-elements # {#pseudo-element-additions}

The <dfn>named view transition pseudo-elements</dfn>
(''view-transition-group()'', ''view-transition-image-pair()'', ''view-transition-old()'', ''view-transition-new()'')
are extended to support the following syntax for each |pseudo|:

<pre class=prod>
::view-transition-group(<<pt-name-selector>><<pt-class-selector>>)
::view-transition-image-pair(<<pt-name-selector>><<pt-class-selector>>)
::view-transition-old(<<pt-name-selector>><<pt-class-selector>>)
::view-transition-new(<<pt-name-selector>><<pt-class-selector>>)
</pre>

where <<pt-name-selector>> works as previously defined, and
<<pt-class-selector>> has the following syntax definition:

<pre class=prod>
<dfn>&lt;pt-class-selector></dfn> = ('.' <<custom-ident>>)*
</pre>

A [=named view transition pseudo-element=] [=selector=] which has one or more <<custom-ident>> values
in its <<pt-class-selector>> would only match an element if the element's [=captured element/class list=]
Copy link
Member

Choose a reason for hiding this comment

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

"would only match an element" is confusing. Can we phrase this as, if the [=captured element/class list=] value in https://www.w3.org/TR/css-view-transitions-1/#viewtransition-named-elements for the pseudo-element's view-transition-name contains all of those values?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed

[=list/contains=] all of those values.

The specificity of a [=named view transition pseudo-element=] [=selector=]
with a <<pt-class-selector>>
is equivalent to a [=class selector=] with the equivalent number of classes.

# CSS rules # {#css-rules}

## The <dfn id="at-view-transition-rule">''@view-transition''</dfn> rule ## {#view-transition-rule}
Expand Down Expand Up @@ -385,6 +493,27 @@ The {{CSSViewTransitionRule}} represents a ''@view-transition'' rule.
:: Null or a [=list=] of strings, initially null.
</dl>

## Additions to [=captured element=] struct ## {#additions-to-captured-element-struct}

<dl>
: <dfn for="captured element">class list</dfn>
:: a [=/list=] of strings, initially empty.
</dl>

## Additions to capture algorithms: ## {#additions-to-capture-algorithms}
Copy link
Member

Choose a reason for hiding this comment

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

How about "view transition class algorithms"? Since this section is the set of algorithm changes required for the view-transition-class property.

<div algorithm="capture old classes">
When capturing the old state of the view transition, perform the following step when iterating on |captureElements| given |element| and |capture|:
Copy link
Member

Choose a reason for hiding this comment

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

Wdyt about pulling steps 2-10 of this loop into a separate algorithm : https://www.w3.org/TR/css-view-transitions-1/#capture-old-state-algorithm:~:text=in%20the%20algorithm.-,For%20each%20element%20in%20captureElements,-%3A. That's where we're setting everything on the "capture" struct given an "element".

Then this spec, "add the following steps to this algorithm".


1. Set |capture|'s [=captured element/class list=] to the [=computed value=] of |element|'s 'view-transition-class'.

</div>

<div algorithm="capture new classes">
When capturing the new state of the view transition, perform the following step when iterating on |captureElements| given |element| and |namedElements|:
Copy link
Member

Choose a reason for hiding this comment

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

I suppose the same thing here for this loop: https://www.w3.org/TR/css-view-transitions-1/#capture-new-state-algorithm:~:text=set%20of%20strings.-,For%20each%20element%20of%20every%20element%20that%20is%20connected%2C%20and%20has%20a%20node%20document%20equal%20to%20to%20document%2C%20in%20paint%20order%3A,-If%20any%20flat.

But I also don't want to explode the number of sub-algorithms in the L1 spec. So if you have any other idea to better link to the exact spot that's good to. Another suggestion is, "Do this after step 4.7 of https://www.w3.org/TR/css-view-transitions-1/#capture-the-new-state". If you like that, I'm happy with the same for above as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's monkey-patchy, I don't like that... let's see what Tab has to say.


1. Set |namedElement|[|transitionName|]'s [=captured element/class list=] to the [=computed value=] of |element|'s 'view-transition-class'.
</div>

## Monkey patches to HTML ## {#monkey-patch-to-html}

<div algorithm="monkey patch to apply the history step">
Expand Down