- From: Noam Rosenthal via GitHub <sysbot+gh@w3.org>
- Date: Tue, 22 Aug 2023 17:26:45 +0000
- To: public-css-archive@w3.org
I wanted to present the 3 ways I think we can go about this. Seems like the discussions are bouncing around between these 3, and we need to choose a strategy. To do this, I'm going to take a use case that's a little above simple, and represents an experience that resembles what early adopters have been doing, and show how this would be implemented using the 3 options.
The use case is as follows:
- main pages: /home, /list, /cart, /product
- for any of these page transitions: slide from right
- but if using back navigation: slide from left
- (/list|/cart)<->/product: also animate product picture
- in addition, internal sections in the page can be reordered using a VT animation.
The options on how to qualify a transition are as follows:
1. single-ident transition type
2. A dictionary of parameters
3. Purely navigation-oriented
All the options would have these routes defined:
```css
@routes {
--home: urlpattern(/((home/?)?)?*);
--cart: url(/cart);
--list: urlpattern(/list\/*);
--product: urlpattern(/product/:id);
--main-page: urlpattern(/(home|cart|list)?\/*);
}
```
## Option 1: single-ident `view-transition-type`
```css
@navigation --main-page to --main-page {
view-transition-behavior: trigger;
view-transition-type: slide-from-right;
}
@navigation back from --main-page to --main-page {
view-transition-type: slide-from-left;
}
@navigation (--list, --product), (--cart, --product) {
view-transition-type: slide-from-right-with-product-picture;
}
@navigation back (--list, --product), back (--cart, --product) {
view-transition-type: slide-from-left-with-product-picture;
}
html:active-view-transition(slide-from-right),
html:active-view-transition(slide-from-right-with-product-picture) {
&::view-transition-group(root) {
animation-name: slide-from-right;
}
}
html:active-view-transition(slide-from-left),
html:active-view-transition(slide-from-left-with-product-picture) {
&::view-transition-group(root) {
animation-name: slide-from-left;
}
}
html:active-view-transition(slide-from-left-with-product-picture),
html:active-view-transition(slide-from-right-with-product-picture) {
#product-picture {
view-transition-name: product-pic;
}
}
html:active-view-transition(reorder) {
#section1 { view-transition-name: section1; }
#section2 { view-transition-name: section2 }
#section3 { view-transition-name: section3; }
}
```
```js
function navigate(newURL, isBack) {
document.startViewTransition({
updateCallback: () => do_navigate(newURL, isBack),
viewTransitionType: ViewTransition.getTypeFromNavigation({
oldURL: location.href,
newURL,
direction: isBack ? "back" : "forward"
});
})
}
function reorder() {
document.startViewTransition({
updateCallback: () => do_reorder(),
viewTransitionType: "reorder"
});
}
```
This feels simple to implement, however it requires a lot of permutations to create idents that cover all the cases.
## Option 2: parameter dictionary
```css
@navigation --main-page to --main-page {
view-transition-behavior: trigger;
--main-page-slide: left;
}
@navigation back from --main-page to --main-page {
--main-page-slide: right;
}
@navigation (cart, product), (list, product) {
--list-to-product: yes;
}
html:active-view-transition(--main-page-slide: left)::view-transition-group(root) {
animation-name: slide-from-left;
}
html:active-view-transition(--main-page-slide: right)::view-transition-group(root) {
animation-name: slide-from-left;
}
htnk:active-view-transition(--list-to-product) {
#product-picture {
view-transition-name: product-pic;
}
}
html:active-view-transition(reorder) {
#item1 { view-transition-name: item1; }
#item2 { view-transition-name: item2; }
#item3 { view-transition-name: item3; }
}
```
```js
function navigate(newURL, isBack) {
document.startViewTransition({
updateCallback: () => do_navigate(newURL, isBack),
viewTransitionParams: ViewTransition.getParamsFromNavigation({
oldURL: location.href,
newURL,
direction: isBack ? "back" : "forward"
});
})
}
function reorder() {
document.startViewTransition({
updateCallback: () => do_reorder(),
viewTransitionType: "reorder"
});
}
```
This feels more compact, however adds a level of indirection that might feel verbose for simple cases.
## Option 3: navigation oriented
```css
@navigation same-origin {
view-transition-behavior: trigger;
}
html {
:active-view-transition(from --main-page to --main-page) {
&::view-transition-group(root) {
animation-name: slide-from-right;
}
}
:active-view-transition(back from --main-page to --main-page) {
&::view-transition-group(root) {
animation-name: slide-from-left;
}
}
:is(active-view-transition(--product, --list), active-view-transition(--product, cart)) {
#product-picture {
view-transition-name: product-picture;
}
}
}
```
```js
function navigate(newURL, isBack) {
document.startViewTransition({
updateCallback: () => do_navigate(newURL, isBack),
navigation: {
oldURL: location.href,
newURL,
direction: isBack ? "back" : "forward"
}
})
}
function reorder() {
document.documentElement.classList.toggle("reordering", true);
document.startViewTransition({
updateCallback(): () => {
document.documentElement.classList.toggle("reordering", false);
}
});
}
```
This seems much more compact, however it means that transition types don't work for element-scoped transitions, and also that for transitions that are not URL-based (like reordering in this case) would need to use the "old" mechanism of toggling classes on the root element.
--
GitHub Notification of comment by noamr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8960#issuecomment-1688622403 using your GitHub account
--
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Tuesday, 22 August 2023 17:26:47 UTC