Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-view-transitions-2] Declarative opt-in for cross-document navigations #8048

Closed
jakearchibald opened this issue Nov 9, 2022 · 93 comments · Fixed by #9382
Closed

[css-view-transitions-2] Declarative opt-in for cross-document navigations #8048

jakearchibald opened this issue Nov 9, 2022 · 93 comments · Fixed by #9382
Labels
css-view-transitions-2 View Transitions; New feature requests Needs Edits

Comments

@jakearchibald
Copy link
Contributor

Cross-document transitions need some way for both the old & new page to opt-in to a transition.

The SPA API uses JS for this, but it would be nice if cross-document transitions didn't depend on JS.

It feels like this should be in CSS, so it can be influenced by media queries, particularly prefers-reduced-motion.

The tricky part here is it's a "global" setting, so it can't be a CSS property.

Proposal:

@cross-document-transition allow;

@media (prefers-reduced-motion) {
  @cross-document-transition deny;
}

However, I'm just making stuff up here. Is there any prior art here for setting 'global' things?

@jakearchibald jakearchibald added Agenda+ css-view-transitions-1 View Transitions; Bugs only labels Nov 9, 2022
@khushalsagar
Copy link
Member

The current proposed API is using a meta tag for this, similar to other Document global settings like viewport meta tag.

But doing this in CSS would be better, for the reasons Jake mentioned like conditionally doing this based on prefers-reduced-motion.

@vmpstr vmpstr removed the Agenda+ label Nov 30, 2022
@khushalsagar khushalsagar changed the title [css-view-transitions-1] [cross-document] Declarative opt-in [css-view-transitions-2] [cross-document] Declarative opt-in Jan 5, 2023
@khushalsagar khushalsagar added css-view-transitions-2 View Transitions; New feature requests and removed css-view-transitions-1 View Transitions; Bugs only labels Jan 5, 2023
@LeaVerou
Copy link
Member

Would it be useful for this to be more fine-grained? I.e. allow transitions from certain pages/domains but not others?

@jakearchibald
Copy link
Contributor Author

Yes, that absolutely should be a goal. My preference would be to allow pages to declare themselves to be of a particular type, which is just an ident. Then you can express that you're happy to perform a transition from "article" to "profile" or whatever.

Although, if we go with URLs, https://wicg.github.io/urlpattern/ will be handy.

@jakearchibald
Copy link
Contributor Author

We chatted with @tabatkins and he's happy with the general shape of the syntax here.

We would need to define what the CSSOM looks like.

It might be worth making @cross-document-transition allow; a shorthand for something like:

@cross-document-transition {
  state: allow;
}

…which would allow us to add other descriptors in future.

In the new page, the opt-in would need to be present before first render. This works out, since CSS in the head is render-blocking.

@noamr
Copy link
Collaborator

noamr commented May 17, 2023

Perhaps it can be a pseudo-state of the ::view-transition rather than a new top-level rule?
e.g. ::view-transition:cross-document, and then you can disable the transition in CSS yourself

::root:has(::view-transition:cross-document) {
  view-transition-name: "none" !important;
}

@bramus
Copy link
Contributor

bramus commented May 17, 2023

Not a fan of this :has() approach. Feels rather hacky.

Iterating on the at-rule – which makes more sense to me – here’s two variants on that:

  1. If more configuration things like this are planned over time (e.g. global custom properties), maybe instead of a new at-rule @cross-document-transition, it could be a descriptor (property?) in @document? I.e. @document { cross-document-transition: allow; }

  2. Maybe, instead of a new at-rule, it would be treated as a media condition? I.e. @media (prefers-reduced-motion and cross-document-transition: allow) { … }

@bramus
Copy link
Contributor

bramus commented May 17, 2023

Oh, wait … that second one doesn’t make sense on its own, as that one doesn’t set anything – it only detects stuff 🤦‍♂️

@noamr
Copy link
Collaborator

noamr commented May 17, 2023

The :has thing is just part of an example, It can also be

@media (prefers-reduced-motion) {
  ::view-transition:cross-document {
    display: none;
  }
}

This allows more fine-grained control over how things behave if this is a cross-document transition rather than totally disabling the transition.

For totally disabling the transitions based on media queries, I'd suggest adding a media attribute to the meta tag, like we have for preloads, or as a parameter to the content attribute, e.g. <meta name="view-transition" content="same-origin;media=(prefers-reduce-motion:no-preference)"> or splitting the opt-in to several meta-tags:

<meta name="view-transition:referrer" content="same-origin">
<meta name="view-transition:media" content="(prefers-reduce-motion:no-preference)">

I'm offering these alternatives because I don't see how using CSS to declare something that's completely global plays to what CSS is good at, and it's also not very consistent with other things CSS does.

@jakearchibald
Copy link
Contributor Author

@font-face and @property are also global declarations in CSS.

@noamr
Copy link
Collaborator

noamr commented May 19, 2023

@font-face and @property are also global declarations in CSS.

They give meaning to all kind of names, but they don't affect the style directly.

@noamr
Copy link
Collaborator

noamr commented May 19, 2023

Thinking about this again.

I see the problem the opt-in tries to solve as mismatch between same-origin transitions. It's not a security problem, but rather an issue of unintended visual effects by having e.g. an SPA transition in both documents lead to a spurious MPA transition between the two documents.

IMO any kind of boolean opt-in doesn't solve this, either in HTML or CSS.
You could opt-in to some MPA transitions within your origin, and still reach a case where some pages are uncoordinated with you and cause an unintended MPA transition.

Instead, I propose something a bit more flexible and : the :root of both documents has to share some sort of name.
It can be the view-transition-name (perhaps if it's not "root", but that might be a bit too implicit), or a new property like a page-transition-name. Only if the names match, the view transition would be enabled.

The purpose in doing something like that is to ensure a match in a flexible way, that's still ergonomic and consistent with how SPA navigations declare matching.

@khushalsagar
Copy link
Member

Instead, I propose something a bit more flexible and : the :root of both documents has to share some sort of name.
It can be the view-transition-name (perhaps if it's not "root", but that might be a bit too implicit), or a new property like a page-transition-name. Only if the names match, the view transition would be enabled.

The problem with this is that UA CSS implicitly adds a view-transition-name to the root element here. So we can't rely on authors setting it as an opt-in. Also, we can't ask for the root of both docs sharing the same name, some transitions require the root of one document to match with a DOM element on the second document, example.

If we're introducing something new (like page-transition-name), then we should avoid overloading it with the same purpose that view-transition-name is for. We also want the opt-in syntax to be extendible to declaratively opt-in to a subset of navigations (same-origin, same-site, URL regex, same-document) which doesn't fit well with reusing what view-transition-name is for.

@noamr
Copy link
Collaborator

noamr commented May 19, 2023

Instead, I propose something a bit more flexible and : the :root of both documents has to share some sort of name.

It can be the view-transition-name (perhaps if it's not "root", but that might be a bit too implicit), or a new property like a page-transition-name. Only if the names match, the view transition would be enabled.

The problem with this is that UA CSS implicitly adds a view-transition-name to the root element here. So we can't rely on authors setting it as an opt-in. Also, we can't ask for the root of both docs sharing the same name, some transitions require the root of one document to match with a DOM element on the second document, example.

If we're introducing something new (like page-transition-name), then we should avoid overloading it with the same purpose that view-transition-name is for. We also want the opt-in syntax to be extendible to declaratively opt-in to a subset of navigations (same-origin, same-site, URL regex, same-document) which doesn't fit well with reusing what view-transition-name is for.

Agreed, but we can flesh this out. The main concept is that this opt in should be by name matching rather than Boolean.

Regarding cross-origin, I think it's a much bigger discussion. This might end up being something with security implications, in which case we would want to have a meta thing, or add a new css property. I don't think that should stop us from having a flexible opt-in for same-origin transitions.

@khushalsagar
Copy link
Member

Regarding cross-origin, I think it's a much bigger discussion.

I don't think we'll be able to ship this for all cross-origin...ever. I specifically meant the same-site case, the security/privacy implications there are not as strict as different domains?

The main concept is that this opt in should be by name matching rather than Boolean.

The fundamental issue with either, a boolean or name matching, is that the syntax is not extendible to even same-origin cases like a subset of pages. For example:

/ * Opt-in for all same-origin navigations */
@view-transition same-origin;

/* Opt-in for same-origin navigations only to URLs which match this pattern */
@view-transition urlPattern(...);

I don't see how name matching or a boolean can be extended to cover this use-case. We've talked about an option like a media query which matches based on old/new URL that potentially could :

@media (old-url: urlPattern(...)) {
   :root { view-transition-name: foo }
}

But that's harder to do since now we have to define the exact time in the old/new Document's lifecycle when this media query activates. I think it's the same problem as defining events to be dispatched on the 2 Documents that you've thought out.

@fantasai
Copy link
Collaborator

I'm not sure that

@view-transition same-origin { trigger: <any-value-other-than-navigation> }

makes any sense. Should it maybe be

@view-transition navigation {
   origin: same-origin;
}

or something else?

@noamr
Copy link
Collaborator

noamr commented Sep 14, 2023

I'm not sure that

@view-transition same-origin { trigger: <any-value-other-than-navigation> }

makes any sense. Should it maybe be

@view-transition navigation {
   origin: same-origin;
}

This doesn't work because it doesn't let you customize classes etc based on URL.
The URLs/types need to be in the matcher rather than in the descriptor.

or something else?

Other suggestions?

@noamr
Copy link
Collaborator

noamr commented Sep 14, 2023

Perhaps

@view-transition navigation(same-origin) {
  behavior: trigger;
}

Later it can be extended like

@view-transition navigation back from same-origin to urlpattern("...") {
  behavior: trigger;
}

@noamr
Copy link
Collaborator

noamr commented Sep 16, 2023

Some more bikeshedding options:

@nav-transition same-origin { behavior: trigger };

@view-transition same-origin-navigation { behavior: trigger }

@navigation-behavior same-origin { view-transition: trigger; }

noamr added a commit to noamr/csswg-drafts that referenced this issue Sep 20, 2023
- Disable view-transitions for reload
- Add wording in security about 3p CSS
- Fire reveal event before rAF, inside update the rendering

Closes w3c#8784
Closes w3c#8889
See w3c#8048
@bokand
Copy link
Contributor

bokand commented Sep 20, 2023

I'm not sure that

@view-transition same-origin { trigger: <any-value-other-than-navigation> }

makes any sense.

Wouldn't this just be an explicit opt-out (which is the default).

If an opt-out that's the default seems redundant, could we just omit trigger entirely? (i.e. the existence of the at-rule implies opt-in). Examples:

@view-transition same-origin-navigation;

@view-transition same-origin-navigation and history-back {
  typeNames: slide-in reverse;
} 

@noamr
Copy link
Collaborator

noamr commented Sep 20, 2023

@view-transition same-origin-navigation;

@view-transition same-origin-navigation and history-back {
  typeNames: slide-in reverse;
} 

It came out in the TAG review that a standalone rule like @view-transition same-origin-navigation; feels a bit inconsistent with the rest of CSS. It's arguable but I can see that point.

@khushalsagar
Copy link
Member

@noamr how does this syntax deal with #8784? We want transitions to not occur for reloads by default but let authors configure it. Since this can be done in script using the navigate event, seems ok if we punt on a declarative hook for it. But I wasn't sure what the plan for that is with this syntax.

@noamr
Copy link
Collaborator

noamr commented Sep 27, 2023

@noamr how does this syntax deal with #8784? We want transitions to not occur for reloads by default but let authors configure it. Since this can be done in script using the navigate event, seems ok if we punt on a declarative hook for it. But I wasn't sure what the plan for that is with this syntax.

In short, @view-transition reload { trigger: navigation} (replace with whatever name we end up with for the rule etc).

The nice thing about reload is that it replaces both the URLs AND the navigation type, so we don't have to bother with composing reloads with other qualifier. A VT-navigation rule is either reload without anything else, or whatever else (same-origin, particular URLs with from/to, back, etc) - mutually exclusive.

@khushalsagar
Copy link
Member

I'm trying to understand what our base qualifiers are. IIUC, the idea is that going forward these base qualifiers can be combined with each other (using and/or operators). I was expecting those to be:

  • from/to URL (to should be post redirects?).
  • navigation type: push, traverse, replace, reload.
  • same-document vs cross-document

same-origin is simply a shorthand for to: urlpattern(/*) (any same-origin URL).

But sounds like you're suggesting reload being another base qualifier which can't be combined with any other qualifier. Is that reasonable? For example, what happens if there is a reload which results in a same-site navigation after redirects. Don't we want authors to be able to express that with something like @view-transition same-site reload { trigger: navigation; }.

@noamr
Copy link
Collaborator

noamr commented Sep 28, 2023

You're right that redirects might make it so that a reload doesn't necessarily mean the same URL/origin, so perhaps it needs to be @view-transition same-origin reload.

About the qualifiers, I'd prefer to look at them more from a user intent standpoint rather than from technical history/navigation terms like push/replace.

"reload" and "back" are clear user experience intents, also "forward", "jump to some place in history", or "jump to a random URL in this origin" (address bar, bookmark, extension etc), and of course a normal navigation like links/forms.

The way I see it, the opt-in rule applies to some of these intents. By default, probably to navigate+forward+back, and arguably jump. It applies to reload only if explicit. So
@view-transition same-origin actually means something like @view-transition (navigate or back or forward) from urlpattern("/*") to urlpattern("/*") and @view-transition same-origin reload means @view-transition (reload) from urlpattern("/*") to urlpattern("/*"). We can perhaps keep the same-origin implicit when reload is present, but I'm not sure we have to decide on this now. Perhaps this discussion can continue in #8784? Not sure it affects the default opt-in that much.

@khushalsagar
Copy link
Member

Sorry I'm still not following how we're dealing with the combination of nav type + from/to url. Every combination of these 2 is possible. So if an author has CSS like:

@view-transition same-site {
  trigger: navigation;
}

@view-transition reload {
  trigger: navigation;
}

What happens if there is a reload which results in a same-site navigation? Your comment above sounds like all the qualifiers are a combination of nav type and from/to url. "same-origin" means any same-origin url of type "navigate", "back" and "forward". Presumably "same-site" would cover the same nav types. And "reload" means only same-origin reload navigations?

We can perhaps keep the same-origin implicit when reload is present, but I'm not sure we have to decide on this now.

Asking this right now because IMO "same-origin" should only be about the from/to url. Overloading the nav type into it is not a good idea. So I'd expect @view-transition same-origin { trigger: navigation; } to include reloads.

@vmpstr
Copy link
Member

vmpstr commented Sep 28, 2023

My interpretation of what @noamr is saying is that we can treat (navigation, back, forward) as the implicit default navigation type.

I agree with @khushalsagar that my understand of same-origin is to be specifically about from/to, and not the type of getting from from to to.

The syntax that I like is something like

@view-transition <<route>> <<navtype>> { ... }

Where

<<route>> = '' | (from: <urlpattern> || to: <urlpattern>) | same-origin | same-site
<<navtype>> = '' | (navigation || back || forward || reload) | including-reload

with an explicit note that explains that if route is '', ie empty, then it is the same as same-origin; if navtype is empty, then it is the same as navigation back forward, but not reload. I've also added including-reload to mean the default ones, and reload, meaning everything.

So with this syntax, I think we can express everything?
Specifically, @view-transition same-origin means it doesn't include reloads, and it's about going from /* to /*.

To answer @khushalsagar's question, in this syntax @view-transition reload means "same origin reload only". If you want to capture all same-site navigations including reloads, then that's @view-transition same-site including-reload.

@noamr
Copy link
Collaborator

noamr commented Sep 28, 2023

Sorry I'm still not following how we're dealing with the combination of nav type + from/to url. Every combination of these 2 is possible. So if an author has CSS like:

@view-transition same-site {
  trigger: navigation;
}

@view-transition reload {
  trigger: navigation;
}

What happens if there is a reload which results in a same-site navigation? Your comment above sounds like all the qualifiers are a combination of nav type and from/to url. "same-origin" means any same-origin url of type "navigate", "back" and "forward". Presumably "same-site" would cover the same nav types. And "reload" means only same-origin reload navigations?

I think so. Mainly because a reload with cross-origin redirects is something that feels unexpected and uncommon. Edge case?

We can perhaps keep the same-origin implicit when reload is present, but I'm not sure we have to decide on this now.

Yes exactly

Asking this right now because IMO "same-origin" should only be about the from/to url. Overloading the nav type into it is not a good idea. So I'd expect @view-transition same-origin { trigger: navigation; } to include reloads.

I see the value in having a clean separation between URLs and types, and having same-origin mean only the URLs.

But I think there is greater value in reasonable defaults. Putting UX first, view transitions on reload is something unexpected and needs to be handled a bit like an edge case, and in most cases not have a transition there at all unless explicitly requested.
This was the tone of this CSSWG resolution.

The same argument for reasonable defaults (which I think is consistent with a lot of CSS) goes for having reloads be same-origin only by default.

As for being conceptually clean, I'd say that in this case same-origin does mean just the from/to URLs, and since there is no type defined, we go with the specified "default set of navigation types" - which are navigate/back/forward/(maybe also jump? not sure).

@khushalsagar
Copy link
Member

The same argument for reasonable defaults (which I think is consistent with a lot of CSS) goes for having reloads be same-origin only by default.

My concern wasn't with the default, but whether the non-default case is possible : reload with a same-site navigation. In general, I'd say our syntax should ensure that any combination of mutually exclusive navigation params (same vs cross doc, from/to url and nav type) can be expressed. We should have a good reason to disallow a combination and it being an edge case is not a good one.

The syntax @vmpstr proposed above sounds good in that regard. One thing I'd say is to include <<doc-change>> to the qualifier as well.

@view-transition <<route>> <<navtype>> <<doc-change>> { ... }

where

<<doc-change>> = "same-document | cross-document"

A few more clarifications around it:

  • Each at-rule declaration must provide a route, nav type and doc-change. If not supplied, there will be a default.
  • The relationship between each qualifier is "and", i.e., the at-rule reads as "navigation to url(a) and back".
  • The default for route is same-origin, nav type is all navigations excluding reload and doc-change is cross-document.

@noamr does that sound reasonable to you?

If the above sounds good then a couple of questions come to mind:

  • I'm assuming we'll allow an "or" type syntax for each qualifier for use-cases like from: urlpattern(a),urlpattern(b). But the relationship between qualifiers is and. So if you want the rule to say "back or navigation to urlpattern(a)", that needs 2 at-rule declarations. That sounds fine to me, just wanted to confirm.
  • Why do we need to require the "same-origin" qualifier? Sounds like similar to nav type, the default value of same-origin avoids the need for it.

@noamr
Copy link
Collaborator

noamr commented Sep 28, 2023

The same argument for reasonable defaults (which I think is consistent with a lot of CSS) goes for having reloads be same-origin only by default.

My concern wasn't with the default, but whether the non-default case is possible : reload with a same-site navigation. In general, I'd say our syntax should ensure that any combination of mutually exclusive navigation params (same vs cross doc, from/to url and nav type) can be expressed. We should have a good reason to disallow a combination and it being an edge case is not a good one.

The syntax @vmpstr proposed above sounds good in that regard. One thing I'd say is to include <<doc-change>> to the qualifier as well.

@view-transition <<route>> <<navtype>> <<doc-change>> { ... }

where

<<doc-change>> = "same-document | cross-document"

I wouldn't do the same-doc thing in CSS at all, rather have this in JS - something like navigation.enableSameDocumentAutoViewTransitions = true which would make this whole thing somehow work magically with the navigation API

A few more clarifications around it:

  • Each at-rule declaration must provide a route, nav type and doc-change. If not supplied, there will be a default.
  • The relationship between each qualifier is "and", i.e., the at-rule reads as "navigation to url(a) and back".
  • The default for route is same-origin, nav type is all navigations excluding reload and doc-change is cross-document.

@noamr does that sound reasonable to you?

If the above sounds good then a couple of questions come to mind:

  • I'm assuming we'll allow an "or" type syntax for each qualifier for use-cases like from: urlpattern(a),urlpattern(b). But the relationship between qualifiers is and. So if you want the rule to say "back or navigation to urlpattern(a)", that needs 2 at-rule declarations. That sounds fine to me, just wanted to confirm.

Not sure yet, I don't think we're there but sounds OK for now.

  • Why do we need to require the "same-origin" qualifier? Sounds like similar to nav type, the default value of same-origin avoids the need for it.

It's not strictly necessary. I think it was your suggestion to make it explicit when reading that this only applies to same origin navigation. I'm ok with also making it an implicit default. It wouldn't be the first thing in the web platform that's implicitly same-origin by default.

@khushalsagar
Copy link
Member

I wouldn't do the same-doc thing in CSS at all, rather have this in JS - something like navigation.enableSameDocumentAutoViewTransitions = true which would make this whole thing somehow work magically with the navigation API

Ok. I'm fine with punting on this.

Not sure yet, I don't think we're there but sounds OK for now.

Aren't we resolving on a syntax which requires an "and" relationship between the qualifiers? I figured that's why we should make sure this is fine right now.

It's not strictly necessary. I think it was your suggestion to make it explicit when reading that this only applies to same origin navigation. I'm ok with also making it an implicit default.

I suggested this because it wasn't clear to me how the syntax will be extended to support same-site. Now that its more clearly laid out, it makes sense to be able to omit it.

@noamr
Copy link
Collaborator

noamr commented Sep 29, 2023

I wouldn't do the same-doc thing in CSS at all, rather have this in JS - something like navigation.enableSameDocumentAutoViewTransitions = true which would make this whole thing somehow work magically with the navigation API

Ok. I'm fine with punting on this.

Not sure yet, I don't think we're there but sounds OK for now.

Aren't we resolving on a syntax which requires an "and" relationship between the qualifiers? I figured that's why we should make sure this is fine right now.

We're not suggesting the qualifiers yet. But I imagine having and/or/() like media queries.

It's not strictly necessary. I think it was your suggestion to make it explicit when reading that this only applies to same origin navigation. I'm ok with also making it an implicit default.

I suggested this because it wasn't clear to me how the syntax will be extended to support same-site. Now that its more clearly laid out, it makes sense to be able to omit it.

Great. Let's suggest this when we discuss the name.

@khushalsagar
Copy link
Member

We're not suggesting the qualifiers yet. But I imagine having and/or/() like media queries.

It's likely fine, I'm just convincing myself that we'll be able to add both and/or operators with the qualifiers later. For example, having no qualifiers implicitly expands to both default values + "and" operator between them. But the author will be able to override the defaults by providing an explicit value for each qualifier + whether its "and"/"or".

@view-transition { ... }

/* The above expands to the following */
@view-transition <<route>> and <<navtype>>  and /* any other potential qualifiers */ { ... }

@view-transition <<route>> or <<navtype>> { ... }

/* The above will expand to the following */
@view-transition <<route>> or <<navtype>>  and /* any other potential qualifiers */ { ... }

Great. Let's suggest this when we discuss the name.

SGTM!

@noamr
Copy link
Collaborator

noamr commented Sep 30, 2023

We're not suggesting the qualifiers yet. But I imagine having and/or/() like media queries.

It's likely fine, I'm just convincing myself that we'll be able to add both and/or operators with the qualifiers later. For example, having no qualifiers implicitly expands to both default values + "and" operator between them. But the author will be able to override the defaults by providing an explicit value for each qualifier + whether its "and"/"or".

@view-transition { ... }

/* The above expands to the following */
@view-transition <<route>> and <<navtype>>  and /* any other potential qualifiers */ { ... }

What are the other potential qualifiers?

@view-transition <<route>> or <<navtype>> { ... }

I think this would expand to (<<route>> and <<default-nav-types>>) or (<<navtype>> and same-origin)

@khushalsagar
Copy link
Member

What are the other potential qualifiers?

Same vs cross-doc was the only other one I had, but I can see that being specified in JS instead of CSS. Can't think of anything else but it's good to ensure its possible to add more going forward.

I think this would expand to (<<route>> and <<default-nav-types>>) or (<<navtype>> and same-origin)

Hmmm, that took me by surprise. Reading the author declaration, that's not what I would've expected. FWIW, @vmpstr pointed out that this use-case can be achieved with 2 blocks like:

@view-tranition <<route>> and all-nav-types { ... }
@view-tranition all-routes and <<navtype>> { ... }

So whichever expansion we take, we won't be limiting authors. We can decide based on what authors would intuitively expect.

@nickcoury
Copy link

One minor comment on

<<navtype>> = '' | (navigation || back || forward || reload) | including-reload

It could be useful to provide an identifier for a multi-entry jump e.g. back(1), navigation(-3), back(*) or something like that. Many well-formed transitions+animations rely on a guarantee on which page(s) can be directly connected.

Jumping between two arbitrary pages that are many navigations apart might generate unexpected motion with VT API annotations, and it would be great to have a way to explicitly disable this or specify a simpler animation like a full-page cross-fade.

This could apply to the opt-in here, and would also be useful for the actual CSS styling specified. Using cascading rules to override will give power to customize e.g.

@view-transition same-site (back(*), forward(*) { trigger: navigation }

::view-transition-old(root) back(*),
::view-transition-new(root) back(*) {
  animation: simple-back-animation;
}

::view-transition-old(root) back(1),
::view-transition-new(root) back(1) {
  animation: advanced-back-animation;
}

(not bikeshedding here with the syntax, just the functionality)

@noamr
Copy link
Collaborator

noamr commented Oct 10, 2023

One minor comment on

<<navtype>> = '' | (navigation || back || forward || reload) | including-reload

It could be useful to provide an identifier for a multi-entry jump e.g. back(1), navigation(-3), back(*) or something like that. Many well-formed transitions+animations rely on a guarantee on which page(s) can be directly connected.

Jumping between two arbitrary pages that are many navigations apart might generate unexpected motion with VT API annotations, and it would be great to have a way to explicitly disable this or specify a simpler animation like a full-page cross-fade.

This could apply to the opt-in here, and would also be useful for the actual CSS styling specified. Using cascading rules to override will give power to customize e.g.

@view-transition same-site (back(*), forward(*) { trigger: navigation }

::view-transition-old(root) back(*),
::view-transition-new(root) back(*) {
  animation: simple-back-animation;
}

::view-transition-old(root) back(1),
::view-transition-new(root) back(1) {
  animation: advanced-back-animation;
}

(not bikeshedding here with the syntax, just the functionality)

Suggesting that back is exactly back(1), and jump is everything else (traversing more than +-1 back/forward, or navigating via URL bar etc)

@khushalsagar
Copy link
Member

jump is everything else (traversing more than +-1 back/forward, or navigating via URL bar etc)

The idea sounds nice but its unfortunate that navigation type in CSS will diverge from navigation type in JS defined by the navigation API. This might be inevitable if we can't change the JS navigation type in a backwards compatible way but worth trying to keep these consistent to the extent possible. @domenic @natechapin FYI.

Could we organize the CSS navigation types as sub-types of the JS versions?

  • push: Needs 2 sub-types to distinguish page initiated (expected transitions) and browser UI initiated (unexpected transitions).
  • reload: Works as-is.
  • replace: Works as-is.
  • traverse: Needs sub-types for back/forward and one to distinguish more than 1 offset traversal aka jump.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-view-transitions-2 View Transitions; New feature requests Needs Edits
Projects
Status: Thursday Afternoon
Development

Successfully merging a pull request may close this issue.