- From: Bramus! via GitHub <sysbot+gh@w3.org>
- Date: Fri, 25 Aug 2023 15:38:40 +0000
- To: public-css-archive@w3.org
_(This reply quickly turned out to be much longer than I expected it to be. It touches a lot of things at once, as they are all interconnected. Please take your time to read it thoroughly as I think it has potential to form an answer to some of the open VT2 questions.)_ I’m also no longer convinced that a single ident that names the transition would cut it. This would require authors to name each and every possible transition between two pages, in each possible direction. That would be a lot of work and a lot of idents. I see 3 parameters that determine how a page-like transition should animate: - The _from_ page - The _to_ page - The _direction_ Combining these 3, you gain a lot of flexibility: - Going _from_ `video-overview` _to_ `video-detail` = Visually slide everything towards the ← side - Going _from_ `video-detail` _to_ `video-overview` = Visually sllde everything towards the → side The reason for this third _direction_, is to cater for transitions between to pages of the same type. Think of a paginated list where you are at page 5. Going to page 4 or to 6 is going to the same type page, but in a different _direction_. - Going _from_ `video-archive` page 5 _to_ `video-archive` page 6 = A `forward` _direction_ = Visually slide everything towards the ← side - Going _from_ `video-archive` page 5 _to_ `video-archive` page 4 = A `backward` _direction_ = Visually slide everything towards the → side Note: when moving between two pages of a different type, you don’t really need the direction as you can achieve the reversed direction by flipping _from_ and _to_ --- Instead of setting these three parameters as a bag of parameters – where an author can choose how to name them - I think we should make it structured and give them proper names. The reason for this, is to play nice with the almighty browser back button. Say you have this: ```js document.startViewTransition({ updateCallback: () => { updateTheDOM(); updateTheURL(); }, to: `video-detail`, from: `video-overview`, }); ``` When the user presses the browser’s back button, it’s now easy very to achieve the opposite transition. Because these arguments are named, the UA can automatically swap the `to` and `from` arguments their values. That way, pressing the browser’s back button after the snippet from just above, is essentially the same as invoking this: ```js // Note: this is the code that would get run when pressing the browser’s back button. The UA automatically re-runs the original View Transition with the to and from arguments swapped. document.startViewTransition({ updateCallback: () => { updateTheDOM(); updateTheURL(); }, to: `video-overview`, // 👈 Swapped value! from: `video-detail`, // 👈 Swapped value! }); ``` For transitions where `to` and `from` were the same, it’s a matter of flipping `forward` to `backward` and vice versa when pressing back. Again, it would be the UA that takes care of this when pressing the browser’s back button after having done such a transition. ```js document.startViewTransition({ updateCallback: () => { updateTheDOM(); updateTheURL(); }, to: `video-archive`, from: `video-archive`, direction: 'backward', // 👈 When going from page 5 to page 4, you are going back in the pagination. }); ``` If you press the browser’s back button after the snippet above, `backward` would become `forward`. Upon pressing the browser’s reload button, the direction would be overridden as `reload`. That way, authors can also take that into account to set up their animations. --- So, what about cross-document Navigation you might wonder? Reusing the `@routes` that was already suggested here it would be a matter of naming the routes. ```css @routes { video-overview: urlpattern('/videos'); video-detail: urlpattern('/videos/watch/:slug'); video-archive: urlpattern('/videos/archive(/:page_id)?'); } ``` Nothing else is needed besides this block (🎉). These route names would then automatically be used as the `from` and `to` arguments when doing a cross-document navigation. The `from` value is derived from the current page URL, and the `to` value from the URL that you end up at. When pressing the browser’s back button, the argument values get swapped. <details> <summary>Sidetracking here: this does not add a way to set the direction to be used.</summary> This should be possible with a little bit of JavaScript but ideally it should also be possible from within CSS. I am thinking of a way to configure this direction in the `@view-transitions` at-rule _([the one that configures VTs](https://github.com/w3c/csswg-drafts/issues/8048#issuecomment-1640574446))_. This would require some sort of pseudo that indicates “hey, this was the element that initiated the cross-document navigation” to hook onto. I’m using `:last-active` here, but the name is definitely up for bikeshedding: ```css .pagination a.next:last-active { @view-transitions { direction: forward; } } .pagination a.previous:last-active { @view-transitions { direction: backward; } } ``` When clicking a link with the class `.previous` for example, the upcoming cross-document transition’s `direction` would be set to `backward`. This pseudo would also offer an answer to https://github.com/w3c/csswg-drafts/issues/8209#issuecomment-1693548146, so that you could use it to set some `view-transition-name` on the fly. Two birds, one stone. </details> --- With same-document navigations being taken care of by requiring authors to set `to`/`from`/`direction` params when calling `document.startViewTransition`, and cross-document-navigation setting these automatically, responding to such a type of transition happens in the same manner for both: look at the values, irrelevant of what navigation it was. In CSS this could be an pseudo _(as already suggested in this thread)_ or an at-rule _(as also suggested in this thread)_. Personally I’m leaning towards an at-rule. _(Note that this at-rule to respond to a VT `@view-transition` – not to be confused with `@view-transitions` which configures VTs.)_ ```css @view-transition (from: video-overview to: video-detail) or (from: video-archive to: video-archive direction: forward) { ::view-transition-old(content) { animation-name: slide-out-to-left; } ::view-transition-new(content) { animation-name: slide-in-from-right; } } @view-transition (from: video-detail to: video-overview) or (from: video-archive to: video-archive direction: backward) { ::view-transition-old(content) { animation-name: slide-out-to-right; } ::view-transition-new(content) { animation-name: slide-in-from-left; } } ``` <details> <summary>Sidetracking here: maybe there would need to be a way to set some things up on the from and to page?</summary> Maybe like this? ```css @view-transition (from: video-overview to: video-detail) { @view-transition :from { /* Set up some view-transition-names on the from page here, if needed */ } @view-transition :to { /* Set up some view-transition-names on the to page here, if needed */ } } ``` Or like this? ```css @route video-overview { /* CSS specifically targeting the video-overview route */ } @route video-detail { /* CSS specifically targeting the video-detail route */ } ``` Anyway, this can be tackled later, as authors can add classes/ids/attributes to their pages and respond to that ```css html[page-type="video-overview"] { /* CSS specifically targeting the video-overview route */ } html[page-type="video-detail"] { /* CSS specifically targeting the video-detail route */ } ``` </details> --- I think this proposal ticks a few boxes: - Don’t break what has already shipped - Same animation CSS for MPA / SPA - Opt-in/opt-out via CSS - Ability to respond to directionality of links _(e.g. following a link from articles list page 2 to page 3 vs from page 2 to page 1; or when clicking the back button of the browser)_ - Note that a navigation can go forward but the directionality of the transition should go backward. _(e.g. when following a pagination link from page 2 to page 1)_ - Ability to take originator of the VT into account _(i.e. respond to which link was clicked in the list)_ This forms an answer to: - https://github.com/w3c/csswg-drafts/issues/8685 - https://github.com/w3c/csswg-drafts/issues/8784 - https://github.com/w3c/csswg-drafts/issues/8683 - https://github.com/w3c/csswg-drafts/issues/8925 - This issue --- What this proposal does not cover are transitions that are not between two pages, i.e. in-page transitions. Think of a page that reorders a set of elements: it can use a View Transition without a navigation happening. For that case I think it’s perfectly fine to ask of authors to use existing methods such as adding a `className` on the transition root if they want to express some type of directionality. After all, they are already relying on JavaScript to do the reordering. ```js document.documentElement.classList.add('reordering'); const transition = document.startViewTransition(() => filterAndReorderElements(filter); ); try { await transition.finished; } finally { document.documentElement.classList.remove('reordering'); } ``` ```css html.reordering { … } ``` Alternatively authors can set from to have a value that is not covered by any route, simply to have a hook to hook onto from within their CSS. Admittedly, this is pretty hacky … ```js document.startViewTransition({ from: 'reordering', updateCallBack: () => { … }, }); ``` ```css @view-transition (from: reordering) { /* Weird, but it works … */ } ``` --- Congrats on making it this far. Thanks for reading 😊 -- GitHub Notification of comment by bramus Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/8960#issuecomment-1693556455 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Friday, 25 August 2023 15:38:43 UTC