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] view-transition-name determined by element #8320

Open
jakearchibald opened this issue Jan 17, 2023 · 64 comments
Open
Labels
Agenda+ F2F Agenda+ css-view-transitions-2 View Transitions; New feature requests

Comments

@jakearchibald
Copy link
Contributor

jakearchibald commented Jan 17, 2023

Thinking of this example https://codepen.io/jaffathecake/pen/VwBprqL

In this case the developer has to manually give each list item a unique view-transition-name. This could be avoided via something like:

.list-item {
  view-transition-name: element-uuid();
}

Where element-uuid() returns a value unique and constant for that DOM node.

The proposal for CSS random() has a per-element value that could be generalised as element-uuid(). #2826 (comment) (cc @tabatkins)

The downside to this is it would only work for same-document transitions, since element-uuid()s will always be different across documents. It also depends on element usage being consistent, which some frameworks don't always get right.

Edit: This would depend on #8319, otherwise styling the resulting pseudos is impossible.

@mirisuzanne
Copy link
Contributor

As @chriscoyier pointed out recently, this solution doesn't really give authors a way to define transitions for the unique names that are generated. How would an author write ::view-transition-* selectors to target these elements with dynamically generated names? In your example, you use the * name selector, but that would target all view transitions on the page. Ideally, we'd be able to target just list-items. Maybe I'm missing something that already makes that possible?

@jakearchibald
Copy link
Contributor Author

jakearchibald commented Jan 19, 2023

I think that's a separate feature #8319, but yes, you would need that feature before this one. I should have mentioned it in the OP.

@tabatkins
Copy link
Member

I don't think we actually want this to be a generic feature, for a few reasons.

  1. As Miriam/[css-view-transitions-2] Creating 'classes' of transition groups #8319 points out, having it be just the randomly-generated identifier isn't actually very useful, and you instead want to be able to group them in some targetable way while giving them unique identities. That's something fairly specific to view-transitions.
  2. As @dbaron points out over in the Toggle repo, having computed styles be unique per element defeats some style-sharing optimizations that are pretty nice to keep. In the toggle case, the common case we need to care about is referencing the sibling index of the element, which we can defer resolving until used-value time; I think this would fall into the same bucket, where all you need at computed-value time is the idea that the names are unique in some way, but they don't actually need to become unique until used-value time.

So I instead recommend having view-transitions define a custom way of saying "this thing has a name, but also is unique based on element identity in a way that's not exposed directly but does affect before/after matching". Maybe just view-transition-name: foo unique; or foo per-element?

@jakearchibald
Copy link
Contributor Author

I'm happy to sit on this one for a bit. #8319 is higher priority.

@noamr
Copy link
Collaborator

noamr commented Oct 10, 2023

Suggesting that a solution to this should take #8319 (comment) into account, and build upon #9141 as a way to dynamically generate unique idents.

For example, given a playlist of songs, all of the songs can have a song view-transition-name, but also each one of them needs a unique one (if for example this is a sort animation). So the song would need something like a song-123 name.

The idea in #9141 is to concat it from attributes, e.g. view-transition-name: ident("song-" attr(id)).
The big advantage over using something like element-uuid() is that this can work across documents - you generate the ID from existing HTML data rather than from some internal browser state that can't carry over between documents.

This is also flexible in a way that DOM order can be used instead of attributes, e.g. with the counter() function:
view-transition-name: ident("item-" counter(list-foo)) or any result of a calc: ident("item-" mod(var(--something), 3).

@khushalsagar
Copy link
Member

@tdresser shared an interesting observation today, frameworks like React have a concept of a unique key for list items : https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key. It seems like instead of a native API, where we can only assume element identify via the corresponding Node, it would be cool to leverage such concepts within the frameworks. Maybe add an API which makes hooking up a custom attribute to the CSS property value easier?

@mirisuzanne
Copy link
Contributor

As someone who is very often not using one of these frameworks, it doesn't feel like a great solution to me.

@jakearchibald
Copy link
Contributor Author

@mirisuzanne are you otherwise happy with a feature that would only work same-document transitions?

@noamr
Copy link
Collaborator

noamr commented Jan 4, 2024

I wonder what people think about an idea like this:

section.list li.item[:id] img { view-transition-name: item-[:id] }

Where the attributes are captured in the selector chain and then used to generate a name.

@mirisuzanne
Copy link
Contributor

Oh, my happiness. Interesting… :)

I'm not actually opposed to a feature that makes it easier for third-party tools to assist in the cross-document functionality. I just hope we also keep working towards a solution that doesn't rely on frameworks?

@noamr I think your proposal still has the cross document issue? Those IDs would be specific to a given document?

@noamr
Copy link
Collaborator

noamr commented Jan 4, 2024

Oh, my happiness. Interesting… :)

I'm not actually opposed to a feature that makes it easier for third-party tools to assist in the cross-document functionality. I just hope we also keep working towards a solution that doesn't rely on frameworks?

@noamr I think your proposal still has the cross document issue? Those IDs would be specific to a given document?

You can have elements with the same IDs on the new document, eg if the IDs come from some database.

@bramus
Copy link
Contributor

bramus commented Jan 5, 2024

(#) I wonder what people think about an idea like this:

section.list li.item[:id] img { view-transition-name: item-[:id] }

Where the attributes are captured in the selector chain and then used to generate a name.

Interesting. I like how this allows you to capture an attribute from a parent element and use that on a child. With attr() that’s not immediately possible, unless you jump through some hoops using a custom property.

Two thoughts:

  • I would use something different than : to capture it, as it could be confused with pseudos. Am thinking of an @ right now:

    section.list li.item[@id] { … }
  • To use it in an ident, I think we’d still need somethink like [css-values] A way to dynamically construct custom-ident and dashed-ident values #9141 to dynamically construct the resulting ident.

    section.list li.item[@id] {
        view-transition-name: ident("item-" @id);
    }

    (Am using @id to refer to the local variable here)

@noamr
Copy link
Collaborator

noamr commented Jan 5, 2024

(#) I wonder what people think about an idea like this:
section.list li.item[:id] img { view-transition-name: item-[:id] }
Where the attributes are captured in the selector chain and then used to generate a name.

Interesting. I like how this allows you to capture an attribute from a parent element and use that on a child. With attr() that’s not immediately possible, unless you jump through some hoops using a custom property.

Two thoughts:

Isn't the ident function redundant though? why not "item-" @id or item-(@id) or something like that?

@jakearchibald
Copy link
Contributor Author

One issue with that syntax is it allows you to capture an attribute named n from only one element in the chain. As in, you can't do: .one[@foo] .two[@foo], because now you have two @foo and no way to differentiate them.

I don't like the naming/syntax here, but you could do something like:

:capture-for-attr(.one, 'one') :capture-for-attr(.two, 'two') {
  view-transition-name: captured-attr('one', 'foo') captured-attr('two', 'foo');
}

:capture-for-attr(selector, name) - where selector is processes as normal, but the selected element is stored as name.

captured-attr(name, attribute) - like attr(), but the first arg is the name of something captured earlier in the selector.

This all feels very complicated though.

@noamr
Copy link
Collaborator

noamr commented Jan 5, 2024

I think that if we wanted to support multiple attributes with the same name in the future we could add something like:

.one[@id1:id] .two[@id2:id] { view-transition-name: "something" @id1 @id2 } 

(JS destructuring assignments have the same problem and a similar sollution)

If we go with verbose function-style I'd rather use the more conservative attr+CSS-variables.

@bramus
Copy link
Contributor

bramus commented Feb 5, 2024

A while back I ran a poll (Twitter, Mastodon) asking authors what is missing from View Transitions. Out of the 33 replies, 6 requested this feature, making it the number 1 request (along with retargetable transitions and scoped transitions)

@mirisuzanne
Copy link
Contributor

mirisuzanne commented Feb 9, 2024

I'm curious what the .foo[@id] selector syntax adds in this proposal. On the other end, item-[@id] seems like a nice concise syntax equivalent to e.g. item- attr(id, ident)). If we can access attributes as idents (or interpolate them into idents), I'm not sure if the selector-side syntax bring anything new to the equation? Having a value-side shorthand for accessing attributes as idents might still be useful - it's certainly simpler to write.

@noamr
Copy link
Collaborator

noamr commented Feb 9, 2024

I'm curious what the .foo[@id] selector syntax adds in this proposal. On the other end, item-[@id] seems like a nice concise syntax equivalent to e.g. item- attr(id, ident)). If we can access attributes as idents (or interpolate them into idents), I'm not sure if the selector-side syntax bring anything new to the equation? Having a value-side shorthand for accessing attributes as idents might still be useful - it's certainly simpler to write.

Which ID would you pick, given:

section[id] > li[id] label * { view-transition-name: item-[@id] }`

Without @ at the selector we'd have to assume that you mean the attribute on the selected element, but that's not always the case.

@jensimmons
Copy link
Contributor

I'm making a simple demo that uses View Transitions to animate enlarging an item that's laid out with CSS Grid, and shifting the other items in the grid around. I was surprised to learn that 1) I have to use JavaScript to use View Transitions, and 2) that I have to give each item in the Grid a unique view-transition-name, and there's no mechanism for applying the functionality to all items.

This caused me to have to write this code:

	.card:nth-child(1) { view-transition-name: card-1; }
	.card:nth-child(2) { view-transition-name: card-2; }
	.card:nth-child(3) { view-transition-name: card-3; }
	.card:nth-child(4) { view-transition-name: card-4; }
	.card:nth-child(5) { view-transition-name: card-5; }
	.card:nth-child(6) { view-transition-name: card-6; }
	.card:nth-child(7) { view-transition-name: card-7; }
	.card:nth-child(8) { view-transition-name: card-8; }
	.card:nth-child(9) { view-transition-name: card-9; }
	.card:nth-child(10) { view-transition-name: card-10; }
	.card:nth-child(11) { view-transition-name: card-11; }
	.card:nth-child(12) { view-transition-name: card-12; }
	.card:nth-child(13) { view-transition-name: card-13; }
	.card:nth-child(14) { view-transition-name: card-14; }
	.card:nth-child(15) { view-transition-name: card-15; }
	.card:nth-child(16) { view-transition-name: card-16; }
	.card:nth-child(17) { view-transition-name: card-17; }
	.card:nth-child(18) { view-transition-name: card-18; }
	.card:nth-child(19) { view-transition-name: card-19; }
	.card:nth-child(20) { view-transition-name: card-20; }
	.card:nth-child(21) { view-transition-name: card-21; }
	.card:nth-child(22) { view-transition-name: card-22; }
	.card:nth-child(23) { view-transition-name: card-23; }
	.card:nth-child(24) { view-transition-name: card-24; }
	.card:nth-child(25) { view-transition-name: card-25; }
	.card:nth-child(26) { view-transition-name: card-26; }
	.card:nth-child(27) { view-transition-name: card-27; }
	.card:nth-child(28) { view-transition-name: card-28; }
	.card:nth-child(29) { view-transition-name: card-29; }
	.card:nth-child(30) { view-transition-name: card-30; }
	.card:nth-child(31) { view-transition-name: card-31; }
	.card:nth-child(32) { view-transition-name: card-32; }
	.card:nth-child(33) { view-transition-name: card-33; }
	.card:nth-child(34) { view-transition-name: card-34; }
	.card:nth-child(35) { view-transition-name: card-35; }
	.card:nth-child(36) { view-transition-name: card-36; }
	.card:nth-child(37) { view-transition-name: card-37; }
	.card:nth-child(38) { view-transition-name: card-38; }
	.card:nth-child(39) { view-transition-name: card-39; }
	.card:nth-child(40) { view-transition-name: card-40; }
	.card:nth-child(41) { view-transition-name: card-41; }
	.card:nth-child(42) { view-transition-name: card-42; }
	.card:nth-child(43) { view-transition-name: card-43; }
	.card:nth-child(44) { view-transition-name: card-44; }
	.card:nth-child(45) { view-transition-name: card-45; }
	.card:nth-child(46) { view-transition-name: card-46; }
	.card:nth-child(47) { view-transition-name: card-47; }
	.card:nth-child(48) { view-transition-name: card-48; }
	.card:nth-child(49) { view-transition-name: card-49; }
	.card:nth-child(50) { view-transition-name: card-50; }

Which is not robust — what if there are more than 50 items on the Grid?? The experience will break.

It seems View Transitions was designed with the expectation that websites are JavaScript first — that it's fine if every items needs to be uniquely named, a developer can just use JS to create all the HTML, and inline styles with JS-created names.

@jensimmons
Copy link
Contributor

This would be a much better solution: .card { view-transition-name: auto; }

@noamr
Copy link
Collaborator

noamr commented Mar 27, 2024

This would be a much better solution: .card { view-transition-name: auto; }

See discussion above - the problem with this solution is that it doesn't work for cross-document, or if the framework recreates the element. Generating the name from attributes is perhaps more verbose but works for all those use-cases.

@bramus
Copy link
Contributor

bramus commented Mar 27, 2024

It seems View Transitions was designed with the expectation that websites are JavaScript first

This is only the case for Same-Document View Transitions. For Cross-Document View Transitions JavaScript is not mandatory.

(And, in the future, there could always be worked on defining some non-JS based triggers for Same-Document View Transitions)

This would be a much better solution: .card { view-transition-name: auto; }

While that could solve some Same-Document View Transitions, this solution won’t work for:

  • Cross-Document View Transitions.
  • Frameworks that trash and re-add nodes as they see fit.

This is also discussed earlier in this thread.

Also see the discussions in #9639 and #9141 which are concerned with solving this naming problem.

@bramus
Copy link
Contributor

bramus commented Apr 30, 2024

Agenda+’ing this one as I think it’s ready for discussion at the meeting.

Proposal:

Why not only attr()?

  • If you only have attr() an author would need to give each and every element a unique [id] (or whatever attribute they may use). At that point they’re back to “naming each and every element individually”: card is card-1, title is title-1, photo is photo-1, … rinse and repeat for each and every card+title+photo.
  • Authors already often give wrapping elements a unique name (e.g. the card wrapper gets a unique [id]). With ident() authors then use that value from the card on child elements such as the title, photo, etc.
  • See [css-view-transitions-2] view-transition-name determined by element  #8320 (comment) for an example.

Why ident() and not allow setting some “strings” as the value?

Why not auto?

  • Doesn’t work with MPA
  • Doesn’t work with nodes that get replaced in between renders (something frameworks often doe, or authors directly manipulating innerHTML on some parent).
  • Doesn’t work when transitioning between two different elements (e.g. from the <h2> in one state to the <span> in the other)
  • Doesn’t allow setting custom animations.
    • For that you would need view-transition-class to target all, set a specific view-transition-name after all to target just the one.
  • If DOM order is used as the counting mechanism this would not work when nodes from a group of siblings get removed as all nodes after the one that got removed get their index adjusted.
  • auto is a solution for View Transitions only. The proposed ident() not only works with view-transition-name but also with scroll-timeline-name, anchor-name, container-name, etc.

@bramus bramus added the Agenda+ label Apr 30, 2024
@jakearchibald
Copy link
Contributor Author

Minor thought on auto vs element-uuid().

Imagine this, which uses the ident() proposal above:

.card {
  --card-id: element-uuid();
  view-transition-name: ident(var(--card-id));

  img {
    view-transition-name: ident(var(--card-id) "-img");
  }
}

This works as long as the card elements remain the same elements, but it works even if the img within is a different element.

That doesn't seem possible with auto.

@fantasai
Copy link
Collaborator

fantasai commented May 7, 2024

Do note that auto would work in Jen’s case as the code is not using any custom animations. Once an author wants to use a custom animation, auto itself can’t help you there. When everything is set to auto, how would you apply custom animations onto them: ::view-transition-group(?whatgoeshere?)?

Using view-transition-class, obviously.

(#8320 (comment)) To address things that move or disappear, authors can use unique tags for those items. So let's say you have a list of 10 items and you're moving item 8 to be the 2nd item. You identify that item with a unique name, and the rest of the items with a generic one, and the UA matches them up in DOM order.

Removing nodes is not covered by this. Take a list of 10 items where you remove item 2 wrapped in a View Transition. All items after the original item 2 get the numbers 3-10 in the old snapshot but 2-9 in the new snapshot – they won’t line up.

Not sure what's the problem... You label the item you're removing as "--special-item" and the rest as "--normal-item" and everything should line up just fine?

It would only address the use case of animating grid positions if the underlying mechanism used for it is an SPA, with a framework that doesn't replace elements.

This is fine. Not everyone is building an "SPA". View Transitions can be used to do nice animations for simpler changes within a web page, such as in @jensimmons's demo. Fancy counting functions and string concatenation for building out custom IDs is nice but... if you don't need them, why do we need to require them? We shouldn't require authors to use complicated mechanisms to do simple things.

In general, the CSSWG shouldn't be designing features for large complicated websites only, but also make things easy to use for smaller, simpler websites (and parts of websites) also. Authors can step up to more complicated solutions as they need them, we shouldn't force them into it prematurely.

@khushalsagar
Copy link
Member

I +1 the idea of autogenerating names without requiring the author to assign an id to every element. But I prefer an approach which uses node identity to generate names over DOM ordering. The DOM ordering approach is more subtle in that small unrelated changes to the DOM can affect how elements are being matched up.

A node identity based approach is possible with both syntax options: view-transition-name: auto or view-transition-name: element-uuid(). I lean towards the latter because of the use-case @jakearchibald pointed to.

@fantasai node identity based generated names should work for the use-case @jensimmons brought up. Would you still want us to use DOM ordering for this..?

@nt1m
Copy link
Member

nt1m commented May 7, 2024

Minor thought on auto vs element-uuid().

Imagine this, which uses the ident() proposal above:

.card {
  --card-id: element-uuid();
  view-transition-name: ident(var(--card-id));

  img {
    view-transition-name: ident(var(--card-id) "-img");
  }
}

This works as long as the card elements remain the same elements, but it works even if the img within is a different element.

That doesn't seem possible with auto.

Practically, I don't see how this is different from:

.card {
  view-transition-name: element-uuid();

  img {
    view-transition-name: element-uuid();
  }
}

In which case, auto would also do the job.

@khushalsagar
Copy link
Member

^ view-transition-name: ident(var(--card-id) "-img"); version means even if the img node changes but the ancestor container card node remains the same, you still get a consistent name.

@nt1m
Copy link
Member

nt1m commented May 7, 2024

I personally don't see much point in removing and recreating the img in this case instead of just mutating it (which is the only thing that would cause the uuid to change), but sure, this is something auto wouldn't easily do.

@khushalsagar
Copy link
Member

It seems nicer since it's able to support more use-cases. And the syntax doesn't seem any complicated than the auto option. So my perspective is... why not go with the element-uuid() option.

@nt1m
Copy link
Member

nt1m commented May 7, 2024

The reason I'm reluctant to it is because element-uuid() feels less CSS-like, and almost like pointer manipulation (you can think of element-uuid() as the address to the element and ident() as a way to manipulate it). It's easier to teach auto than element-uuid() IMO.

Perhaps it's more syntax bikeshedding at this point, but I would rather have some syntax that abstracts away things and feels more like CSS. It doesn't need to necessarily be auto, but not something that feels as low-level as element-uuid().

@nt1m
Copy link
Member

nt1m commented May 7, 2024

I don't have a proposal on top of my head aside from auto but I hope the working group can take that in account when designing the syntax.

@jakearchibald
Copy link
Contributor Author

jakearchibald commented May 8, 2024

@nt1m

I personally don't see much point in removing and recreating the img in this case instead of just mutating it

When mutating something like an image, the old image sticks around until enough of the new image has loaded. This is often undesirable (especially given that width and height changes apply immediately), and a quick fix is to recreate the element, so you get the initial element loading experience.

More generally, when developing with frameworks, it's somewhat trickier to preserve element identity than it is to force new element creation.

It's easier to teach auto than element-uuid() IMO.

I don't agree. I think if you asked developers what they think the two do, you'll get something more accurate with element-uuid(), because its name describes what it does. auto means lots of different things across CSS properties. You have to learn what it does on a case by case basis.

element-uuid() gives you an auto-generated ID that's consistent for the life of the element. The same element will always have the same element-uuid(). A different element will have a different element-uuid().

Now let's do auto:

When view-transition-name is auto, it's given an auto-generated name that's consistent for the life of the element. The same element will always have the same auto-generated name. A different element will have a different auto-generated name.

🤷

I would rather have some syntax that abstracts away things and feels more like CSS

I don't think you're abstracting much away. The auto generated name will probably appear as the group name.

As for 'feels', I really think we should focus on more objective things, but element-uuid() feels at home with things like sibling-index().

@nt1m
Copy link
Member

nt1m commented May 8, 2024

As for 'feels', I really think we should focus on more objective things, but element-uuid() feels at home with things like sibling-index().

This isn't just about feels. element-uuid() is odd to me because CSS tries to detach itself from the host language and this exposes something new from the host language (that the host language doesn't even have access to in JS!).

I don't think you're abstracting much away. The auto generated name will probably appear as the group name.

In my proposal, the computed value would just stay auto, for styling you'd use view transition classes (you wouldn't be able to use names either way since you can't really predict an auto-generated name).

I don't agree. I think if you asked developers what they think the two do, you'll get something more accurate with element-uuid(), because its name describes what it does. auto means lots of different things across CSS properties. You have to learn what it does on a case by case basis.

Fwiw, auto could be named differently if it's too vague (from-element e.g. like text-decoration-thickness: from-font).

Just to be clear though, I'm not advocating for a particular syntax. I'm open to a different one that addresses more use-cases but I think honoring how CSS was designed is important IMO. I wonder if @fantasai or @tabatkins have ideas here.

@noamr
Copy link
Collaborator

noamr commented May 8, 2024

It would only address the use case of animating grid positions if the underlying mechanism used for it is an SPA, with a framework that doesn't replace elements.

This is fine. Not everyone is building an "SPA". View Transitions can be used to do nice animations for simpler changes within a web page, such as in @jensimmons's demo. Fancy counting functions and string concatenation for building out custom IDs is nice but... if you don't need them, why do we need to require them? We shouldn't require authors to use complicated mechanisms to do simple things.

A lot of use cases fall in the middle between that demo and a full-blown SPA, there's no clear dichotomy. By allowing auto (or element-uuid()) we're guiding some authors into a "why did this stop working?" corner at some point in their development journey. In some organization the person writing the CSS and the person deciding on these frameworky underlying mechanism would not even be the same one...

Since

  1. the not-yet-implemented ident concatenation does solve the issue to a great extent
  2. the ergonomic simple solutions are kind of a shorthand version, and the main thing they add apart from ergonomic is not needing an attribute
  3. for the full-blown SPA/MPA use case we anyway need something like ident/attr, so auto/element-uuid doesn't cover the range of use-cases

perhaps we should spec & implement ident+attr first, and defer this conversation until after we've received feedback from developers that they're too verbose for some use cases?

@jakearchibald
Copy link
Contributor Author

jakearchibald commented May 8, 2024

@noamr I appreciate the reframing.

I do worry that the use-cases being tackled here are ones that pop up for little demos, but aren't such a big issue in 'real' development.

In real apps/sites, it's pretty easy to assign items a unique ID. ident() + attr() helps a bit, but not loads. auto/element-uuid is SPA only, and ensuring that element references are stable is harder in frameworks than just assigning a unique ID (not everyone uses a framework, but I think it's fair to say SPA apps that want to perform transitions between states will skew that way).

The biggest help here has been transition classes.

Aside from that, it feels like a lot of effort is being spent here that could be better spent on something like nested transition groups, which would unblock a bunch of transitions.

@vmpstr
Copy link
Member

vmpstr commented May 13, 2024

All of the proposed solutions are not exclusive. The simplicity of auto or from-element should not be downplayed because large sites need something more powerful.

The element identity matching seems to be already present to some extent in content-visibility, contain-intrinsic-size's last remembered size, and maybe "last remembered" thing in anchor positioning. They all mention something along the lines of "if the element did X in the past, then do Y" which breaks under element thrashing. I'm not necessarily suggesting adding more breaking behavior, but I'm also not seeing a compelling reason why view transitions are different here. Is element thrashing common in "real" sites? DOM recycling is maybe a concern, but developers should know how to deal with it.

I'm fine with trying ident/attr solution first, but isn't this just moving the naming problem from CSS to DOM? It doesn't at all address the "demo" cases, and the fact that a lot of DOM may already have unique ids on elements in "real world" cases seems coincidental at best

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-view-transitions-2] view-transition-name determined by element .

The full IRC log of that discussion <emilio> vmpstr: unique names for transitions is cumbersome because authors need to come up with a bunch of unique names
<emilio> ... various proposals
<emilio> ... one is to have v-t-n: auto / from-element which matches with element identity
<emilio> ... so as long as it doesn't change it works nicely
<emilio> ... but it doesn't work with cross-document transitions
<emilio> ... and also for frameworks that might replace the dom nodes
<emilio> ... another proposal is `element-uuid()` but it's effectively the same as above, just more explicit
<emilio> ... another one is `attr()`, which would work for cross-document v-t and frameworks
<emilio> ... my proposal would be to do both
<khush> q?
<emilio> ... leaving attr for more advanced use cases
<emilio> q+
<astearns> ack fantasai
<emilio> fantasai: I think doing both (`auto` / `from-element` and `attr()`) makes sense
<emilio> ... there was another idea in the thread which needs more thought
<emilio> ... right now we restrict v-t-n to be unique
<emilio> ... if it's not it gets ignored or something, it's an error condition
<emilio> ... in a bunch of cases, let's say you're reordering a list or so you don't necessarily want to number them all
<emilio> ... if we could have multiple names and we could number them somehow automatically that might help
<emilio> ... but that might be doable in addition to these things
<astearns> ack emilio
<fantasai> s/reordering/shifting items after inserting into/
<flackr> emilio: my main concern is how likely is it for someone to use from element and not realize it doesn't work for cross document?
<flackr> emilio: from where i stand it seems obv it doesn't work, but requires some internals knowledge
<astearns> q+
<flackr> emilio: just a mild concern, not blocking.
<emilio> ack fantasai
<Zakim> fantasai, you wanted to answer emilio's question
<astearns> ack fantasai
<emilio> fantasai: vt has been focused on the fact that you have "pages", and you're changing pages from one page in a web app to another one
<emilio> ... but lots of transitions authors can do are single-page
<emilio> ... and sometimes view-transitions is the best tool
<emilio> ... for those cases this element identity stuff it's not an issue
<ydaniv> +1
<flackr> emilio: for those use cases this is fine, it just feels like it might be confused
<flackr> emilio: or worse the browser could accidentally have a same pointer
<flackr> emilio: i guess that's just a bug
<emilio> flackr: my comment is somewhat related
<astearns> ack flackr
<emilio> ... while I agree that attr() should be supported
<emilio> ... if the common case is an identity
<emilio> ... maybe we can roll it into `auto` in-some cases
<emilio> ... so if element has an `id` attribute then `auto` would take that
<fantasai> interesting
<emilio> ... or an ancestor one or something
<emilio> vmpstr: we still need to define for the `auto` cases
<emilio> ... we still need some identifier that an author can see
<emilio> ... I think the element's uuid is a good choice there
<fantasai> -1 to uuid
<emilio> ... but we haven't thought too much about it
<emilio> q+
<fantasai> if the author wants to reference it they should give it a name
<khush> q+
<fantasai> using the id attribute
<emilio> astearns: I think the automatic number is interesting but has a different set of failure modes that it probably could be a separate issue
<vmpstr> it's about the param in ::view-transition-group(param) etc, not sure what to put there, or leave it as "auto"?
<emilio> ... I wanted to push back a bit, it seems a bit of a smell that people don't want to put unique names in css so we make them put it on the markup?
<astearns> ack astearns
<astearns> ack fantasai
<Zakim> fantasai, you wanted to respond to astearns
<emilio> fantasai: a lot of times you have these unique ids already
<emilio> ... so you might as well just reuse them
<astearns> ack emilio
<fantasai> I like flackr's idea of having `auto` take the ID if it has one, and fall back to element identity matching otherwise
<flackr> emilio: just want to confirm, allowing attr would make this id mutable in some interesting ways. I guess we have a well defined point where we collect them so it doesn't add much complexity, right?
<astearns> q+
<flackr> khush: I imagine it's similar to attribute changes requiring recomputing style
<flackr> emilio: my point is, if the mutation happens after we start the transition, then presumably it shouldn't count? This detail probably needs to be mentioned
<flackr> khush: this is called out already for view-transition-name as it's an issue already for name changes
<flackr> emilio: sounds good
<flackr> emilio: the auto thing seems like it could use a bit more work since as vmpstr mentioned the name is exposed in the css. My slight preference is to resolve attr and figure out auto later
<flackr> emilio: happy to also resolve on auto and resolve the details later
<astearns> ack khush
<emilio> khush: +1 to fantasai, attr() is useful where you already have unique names for your items without having to use JS
<emilio> ... the other thing is, I think we'll have an easier time resolving on attr()
<flackr> +1 as well, css is often in a separate file and not unique per element
<emilio> ... for auto / from-element vs element-uuid
<emilio> ... there was an example where element-uuid could be used to name an ancestor or child of an element rather than auto
<emilio> ... auto would only allow to set the id on that element itself
<flackr> q+
<emilio> ... one other point was that anything that ties with element identity it doesn't work for MPA
<emilio> ... we might want to just ignore the name altogether for MPA transitions
<emilio> ... so it's harder to miss
<emilio> ... but I think we should probably resolve on attr() and work on the other details on transitions
<emilio> astearns: I wanted to ask whether it'd make sense to make from-element only work on SPA and reserve auto for something that can work eventually on MPA
<emilio> ... so resolve on from-element for now, and opening an issue on an additional auto which does something along the lines that flackr was suggesting
<emilio> vmpstr: I don't mind the idea but I'd like a different name that from-element
<emilio> ... I'd prefer a different id
<astearns> ack astearns
<astearns> ack flackr
<emilio> ... because from-element seems you're reading something from the element rather than using the element itself
<emilio> TabAtkins: can we take it back to the issue? random() has similar use cases and we should make sure they're in sync
<emilio> flackr: for auto / from-element it was mentioned that this is exposed
<emilio> ... is that necessary?
<emilio> ... are there other ways we could do it?
<emilio> vmpstr: we can hide it by using auto
<emilio> ... we don't currently have the same parameter in the view transition pseudos I don't think it's a problem
<emilio> ... the reason we added v-t-c is similar
<emilio> ... so I think we can hide it
<emilio> flackr: I think you can expose the initial style without a name
<emilio> khush: web animations might be weird because you get a list of pseudos and can't differentiate it
<emilio> ... any place the name would have appeared then it'd be replaced with auto
<emilio> flackr: that's one possibility
<emilio> ... maybe there are others
<emilio> ... worth exploring
<emilio> khush: we use ua css to put styles, we need to figure out how the UA css would work
<emilio> flackr: right, but that can be an implementation detail
<astearns> ack fantasai
<emilio> fantasai: I like flackr's suggestion of auto pulling the id if it has an ID and otherwise uses other way of identity
<emilio> q+
<emilio> fantasai: I agree we want to expose randomly generated IDs into author CSS
<emilio> ... they can given it a name if they need to target something
<fantasai> s/want/don't want/
<emilio> khush: attr() didn't ship for reasons
<emilio> fantasai: let's draft some more concrete proposal
<emilio> ... and come back
<emilio> vmpstr: vague resolution is fine and we can come back with details

@bramus
Copy link
Contributor

bramus commented May 21, 2024

@astearns I see you added the “Needs Edits” label to this thread but I don’t see any resolution in the discussion. Am I overlooking something?

@khushalsagar
Copy link
Member

The conclusion was to have a more detailed proposal for attr()/ident() option and bring this back for a resolution. The group did a soft resolution on the idea.

And more exploration is needed for the auto idea. Using element identity but potentially falling back to the id attribute if set (so it can work for cross-document transitions).

@bramus
Copy link
Contributor

bramus commented Jun 12, 2024

Noticed this wasn’t on the agenda for the F2F, but if there’s time maybe we can discuss?

I think it’s clear what we want auto naming for both simple and complex cases.

  • Simple cases would use auto as a value for the view-transition-name.
  • More complex cases (e.g. more complicated DOM structure, MPA, transition between two different elements) would rely on ident() (from [css-values] A way to dynamically construct custom-ident and dashed-ident values #9141) to generate a predictable unique ident. This can be combined with attr() to get an attribute value, other things like sibling-index(), or even other idents and string values.

The result for authors is that there’s less code and less naming things going on – see this example that uses a polyfill to get the syntax working. Some names are auto-generated, whereas some rely on ident(). The delta with the current approach is 100 LOC removed.

The thing that’s unclear is how auto should work. Trying to interpret the previous discussion it was suggested to try a waterfall of values, starting with the id attribute (which should already be unique), before falling back to an auto-generated value. By the looks of it we were pretty close on this, and maybe can come to a conclusion – even if “auto with details TBD” – now?

@khushalsagar
Copy link
Member

Actually, I think we need a clearer proposal before bringing this back? There were a bunch of open questions about how auto should behave with respect to how the value is decided, how it's exposed to script APIs, whether it should work for MPA etc. So maybe not ready for discussion.

The ident()/attr() one had more consensus. Do you have a proposed resolution there that we could take up today?

@noamr
Copy link
Collaborator

noamr commented Jun 13, 2024

Actually, I think we need a clearer proposal before bringing this back? There were a bunch of open questions about how auto should behave with respect to how the value is decided, how it's exposed to script APIs, whether it should work for MPA etc. So maybe not ready for discussion.

The ident()/attr() one had more consensus. Do you have a proposed resolution there that we could take up today?

Probably #9141 (comment) summarizes it.|
ident() should be a function that creates an ident from concatenated strings, numbers, and other idents, as long as the result is a valid ident. It can be useful even if we don't have attr() yet, e.g. using counter.

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

No branches or pull requests