Skip to content

[css-view-transitions-1] Should view transition names be tree scoped? #10145

Closed

Description

@khushalsagar

The spec currently traverses all DOM elements to look for view transition names, see text here. This should probably be tree scoped similar to other CSS naming conventions like scroll timeline and I'm guessing anchor positioning (@tabatkins ?).

@nt1m fyi.

Activity

  1. noamr commented on Mar 26, 2024

    @noamr
    Collaborator

    +1 to view transition names being tree-scoped. The implication of the current spec/implementation is that custom elements that are supposed to be encapsulated can animate each other's internals if they know the internal vt-names.

  2. nt1m commented on Mar 26, 2024

    @nt1m
    Member

    More work in the implementation but makes sense to me.

  3. css-meeting-bot commented on May 8, 2024

    @css-meeting-bot
    Member

    The CSS Working Group just discussed [css-view-transitions-1] Should view transition names be tree scoped?, and agreed to the following:

    • RESOLVED: view-transition-name lookup is tree-scoped
    The full IRC log of that discussion <fantasai> khush: Spec currently traverses all DOM elements, including those in shadow DOM
    <fantasai> khush: Suggestion is to limit to tree-scoped
    <TabAtkins> +1 to this
    <fantasai> khush: so this would exclude things in shadow DOM
    <fantasai> astearns: I've written some tests for tree-scoping, btw, and interop is terrible
    <fantasai> khush: Are you talking about other features that are similar?
    <fantasai> astearns: Yeah, I did @Property rules and @xxx rules, which are supposed to be tree-scoped, and they're not handled correctly
    <astearns> zakim, open queue
    <Zakim> ok, astearns, the speaker queue is open
    <fantasai> astearns: so probably some other things are also broken
    <emilio> fantasai: two things, khush does this mean that for v-t that you'll never be doing transitions on anything in the shadow dom?
    <emilio> khush: yeah this means that you couldn't use something inside the shadow dom as an independent thing
    <kizu> q+
    <emilio> ... scoped transitions would allow you to do that
    <emilio> ... but only as a unit inside the DOM
    <emilio> fantasai: to alan, there's two different kinds of scoping, at-rules and name defining
    <emilio> ... those are quite different mechanism
    <astearns> ack kizu
    <fantasai> s/defining/defining on elements/
    <emilio> ... I'd expect less issues with things like timeline scopes and so on
    <fantasai> kizu: Wrt other scoping things, we also have timeline-scope and anchor-name
    <fantasai> kizu: Might want to have a way to expose these names, since might have cases where you want to expose
    <khush> q+
    <fantasai> kizu: maybe this is a more general issue that we need to handle in CSS, and have it work consistently
    <astearns> ack khush
    <TabAtkins> +1, we need a general mechanic for weakening shadow encapsulation
    <TabAtkins> But we should be consistent for now
    <fantasai> khush: kizu's point reminds me of ::part(), could use CSS to expose names from within shadow DOM outside it
    <fantasai> khush: maybe if you expose the element could allow it to match
    <fantasai> khush: could make it more complicated to implement
    <fantasai> khush: we already have things in the platform that allow such information, in those cases do you want naming in CSS to also be exposed?
    <fantasai> astearns: That would be a separate feature, though. This is for default behavior for view transitions
    <fantasai> khush: Does it make sense to make this resolution cover other cases also? Have a general principle
    <fantasai> astearns: I think a separate issue on general mechanism, because we do want to consider them all
    <fantasai> astearns: don't want to have a specific escape route just for VT
    <TabAtkins> Agree, separate issues
    <fantasai> RESOLVED: view-transition-name lookup is tree-scoped
  4. shonya3 commented on Jun 16, 2024

    @shonya3

    View-transition names have been working seamlessly inside shadow trees until now. After updating Chrome to version 126, view-transition-name no longer pierces the shadow tree.
    My entire project is built with custom elements (CE), including individual elements, pages, and the root.
    This change has significantly degraded the user experience of my website, and I am currently at a loss for how to address this issue.

  5. reopened this on Jun 17, 2024
  6. vmpstr commented on Jun 17, 2024

    @vmpstr
    Member

    Perhaps we should follow Scroll Timeline example here which treats everything as a flat tree:

    Like most operations in CSS besides selector matching, features in this specification operate over the flattened element tree.

    In ViewTransitions, we limit view-transition-name in this algorithm, but in the same algorithm use flat tree ancestors, which seems contradictory.

  7. 25 remaining items

  8. noamr commented on Jul 1, 2024

    @noamr
    Collaborator

    @noamr Yep, i am sharing across boundaries, something like this or this Bramus explained my case perfectly.

    Gotcha. I see that you're using shadow parts already in the first example? Do you think enabling view-transition-name on ::part like in #10303 work for your use case? Superficially it seems like the right direction.

  9. Remiscan commented on Jul 1, 2024

    @Remiscan

    If I may mention my own use case here: my team is working on an app built entirely with web components, so we have nested components with shadow roots. Chrome 126 broke our View Transitions.

    Enabling view-transition-name on ::part would be a useful solution if we also had scoped View Transitions. Starting a View Transition on a deeply nested custom element, then giving names to its sub-components with ::part sounds doable. But without scoped View Transitions, we'd have to use the exportparts attribute all the way up to the document element, since that's the only element we can start a View Transition on right now, right?

    That sounds very impractical. A solution like a CSS attribute, as mentioned here, looks like it would help us a lot more in that case.

  10. noamr commented on Jul 1, 2024

    @noamr
    Collaborator

    If I may mention my own use case here: my team is working on an app built entirely with web components, so we have nested components with shadow roots. Chrome 126 broke our View Transitions.

    Enabling view-transition-name on ::part would be a useful solution if we also had scoped View Transitions. Starting a View Transition on a deeply nested custom element, then giving names to its sub-components with ::part sounds doable. But without scoped View Transitions, we'd have to use the exportparts attribute all the way up to the document element, since that's the only element we can start a View Transition on right now, right?

    That sounds very impractical. A solution like a CSS attribute, as mentioned here, looks like it would help us a lot more in that case.

    Thanks for sharing! Do your transitions cross shadow boundaries (an element in a shadow transitions into an element in another shadow/light DOM etc) or it's more like wanting transitions within the same shadow root to work?

  11. Remiscan commented on Jul 2, 2024

    @Remiscan

    Thanks for sharing! Do your transitions cross shadow boundaries (an element in a shadow transitions into an element in another shadow/light DOM etc) or it's more like wanting transitions within the same shadow root to work?

    The transitions cross shadow boundaries. view-transition-names are set on components nested a few levels deep within a container's shadow root, and the same view-transition-name will be set on different elements, in different shadow roots, between the start and end state of the transition.

    However, there is still a "transition container" element that contains every transitioned element within its shadow root (or its children's shadow roots, or their children's, etc). I feel like ::part could still work within the "transition container" here, provided the correct chain of exportparts is used on the nested children. Then we would move all view-transition-names definitions into the CSSStyleSheet that's adopted by the "transition container" element. (It would also be nice to define the transition itself in that same style sheet, but for now all ::view-transition-* selectors have to be in a separate style sheet adopted by the document.)

    The main pain point remains that we would also have to modify the whole chain of ancestor elements, from the "transition container" all the way up to the root of the document, to use exportparts on them as well to make things work with document.startViewTransition.

    And it would make it harder to move the view-transition-names between the start and end state of the transition: before Chrome 126, some JavaScript could directly set (or remove) the names (or CSS classes) on the appropriate elements during the View Transition update callback. Now, that JS would have to set (or remove) parts instead, and we'd have to make sure they're exported through all ancestors, and set the names from the document.

  12. noamr commented on Jul 2, 2024

    @noamr
    Collaborator

    @Remiscan gotcha. So sounds like in the long run, something like a combination of ::part and element-scoped transition would be ideal for your use case.

    Thanks for sharing in detail, we're discussing a few options internally and want to understand the use cases better.

  13. noamr commented on Jul 3, 2024

    @noamr
    Collaborator

    Summarizing internal conversation about this:

    We're hitting the same snag that we've hit in anchor positioning and view-timeline, where to support ::part (as in #10303) is problematic because it requires tracking of "where did this style come from", and style doesn't always come from a particular tree scope, e.g. it can come from an inline attribute set by a script that's not from a particular tree. See https://drafts.css-houdini.org/css-properties-values-api/#shadow-dom.

    In other specs the current direction is to have these names operate on the flat tree, and scope them using a separate property (e.g. anchor-scope) rather than using the shadow boundary for this scoping. Perhaps we could have a "soft" encapsulation for this by defaulting these scope property to be contained in shadow roots.

    In any case, we should be consistent here and in anchor-positining/scroll-driven positioning.

    Proposing that if anchor positioning and scroll-driven animations don't change course to use shadow encapsulation, including figuring out the "where did the style come from" issue, then we revert the view-transition change so that view-transition-names are in the flat tree to be consistent, and introduce view-transition-scope which would be as consistent as possible with anchor-scope (will prepare a proposal for that).

  14. shonya3 commented on Jul 3, 2024

    @shonya3

    @noamr Yep, i am sharing across boundaries, something like this or this Bramus explained my case perfectly.

    Gotcha. I see that you're using shadow parts already in the first example? Do you think enabling view-transition-name on ::part like in #10303 work for your use case? Superficially it seems like the right direction.

    Enabling view-transition-name for ::part looks logical and natural to me.

    But the main concern for me is whether it will work without much hassle.

  15. andruud commented on Jul 3, 2024

    @andruud
    Member

    In other specs the current direction is to have these names operate on the flat tree, and scope them using a separate property (e.g. anchor-scope) rather than using the shadow boundary for this scoping.

    No, anchor positioning is tree-scoped, and there's no plan to change it. I think the issue and proposal in #10325 was just misunderstood. The anchor-scope property does not replace tree-scoping, it's just an additional mechanism on top of it.

    Scroll-driven animations however is more like what you describe. For some reason I never understood, timeline names are not tree-scoped. #8135. But I'm not sure we should draw inspiration from this, we might want to fix SDA instead.

  16. noamr commented on Jul 3, 2024

    @noamr
    Collaborator

    Thanks @andruud, this makes sense. So to clarify, the resolution here is fine and matches anchor positioning, and should also support things like putting a view-transition-name on a ::part, but the way we interpreted it in the implementation (and perhaps in the spec wording?) is a bug.

  17. added a commit that references this issue on Jul 4, 2024
    8936232
  18. added a commit that references this issue on Jul 5, 2024
    eaf34b1
  19. noamr commented on Jul 8, 2024

    @noamr
    Collaborator

    @shonya3 @Remiscan @JudahGabriel as of Chrome M127 you should be able to give a view-transition-name to a ::part in the document scope. I know this is not an ideal solution for every use-case given that we don't have element-scoped transitions yet, but it should at least give you a way to work around the regression you've experienced in the short term. WebKit is following through with the same.

  20. shonya3 commented on Aug 7, 2024

    @shonya3

    Just implemented my first try with new approach.

    index.html

    p-card::part(card),
     p-home::part(card) {
     view-transition-name: card;
    }

    p-home.ts
    Somewhere in render method...
    Conditionally set part="card" attribute

    this.paginated.map(card => {
    	return html`<li>
    		${card === this.activeCard
    			? html`<e-card-with-sources
    					.name=${card}
    					.divcordTable=${this.divcordTable}
    					.cardSize=${this.cardSize}
    					.sourceSize=${this.sourceSize}
    					@navigate=${() => this.#setActiveCard(card)}
    					part="card"
    			  ></e-card-with-sources>`
    			: html`<e-card-with-sources
    					.name=${card}
    					.divcordTable=${this.divcordTable}
    					.cardSize=${this.cardSize}
    					.sourceSize=${this.sourceSize}
    					@navigate=${() => this.#setActiveCard(card)}
    			  ></e-card-with-sources>`}
    	</li>`;
    });

    And there is activeCard?:string global state to set it on p-home render and update on navigate(emits by divination card element on any inner link element click).
    Not too bad, to be honest 🤓
    https://divicards-site.pages.dev/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions