Skip to content

[css-view-transitions-1] CSS selector syntax for generated elements and API names #7788

Closed

Description

@jakearchibald

Folks at TPAC asked for the pseudo-element names to be reduced so we had a bikeshedding session, and here's what we came up with.

@fantasai @mirisuzanne I'm interested to hear your thoughts on this. We've tried to go for brevity rather than full namespacing.

"Shared element transition" becomes "View transition"

Rationale:

  • "shared element" didn't seem accurate. There's no sharing of elements.
  • The DOM changes, and a transition is created from the two states. The actual DOM elements aren't animated, it's just a view of them, so "view transitions".

page-transition-tag becomes
view-name

.header {
  /* old */
  page-transition-tag: header;
  /* new */
  view-name: header;
}

This causes pseudos to be created so the header can be animated independently during the transition.

Rationale:

  • The scope of a transition may not always be the whole "page".
  • Other specs use "name" rather than "tag" to set an identifier (container-name, scroll-timeline-name).
  • Using "view" because "view transition".

html::page-transition becomes
html::view-root

This is the root of the pseudo-element tree that contains all the transition parts.

Rationale:

  • The scope of a transition may not always be the whole "page".
  • Using "view" because "view transition".
  • "root" because it's the root of the pseudo-element tree.

html::page-transition-container(header) becomes
html::view(header)

This is the pseudo-element that represents a view of an element during the transition. In this case it's the view of the 'header'. Developers target this to customize the animation. It's a child of html::view-root.

Rationale:

  • Each element that's given a view-name results in the creation of one of these pseudo-elements. So view-name: header results in a html::view(header) during the transition.

html::page-transition-image-wrapper(header) becomes
html::view-image-group(header)

This wraps the view's images, providing isolation for their blending (to allow a true cross-fade). In this case it's the image-group for the 'header'. It's a child of html::view.

Rationale:

  • The pseudo elements within are replaced elements, but they behave like images. They have a width, height, and an aspect ratio.

html::page-transition-outgoing-image(header) and
html::page-transition-incoming-image(header) become
html::view-before(header) and
html::view-after(header) respectively

These are the replaced elements that represent the before and after view. In their default animation, they cross-fade.

Rationale:

  • Folks had difficulty mapping 'outgoing' and 'incoming'.
  • 'before' and 'after' seem more intuitive, and shorter.
  • The web animation API uses language like "before phase" and "after phase", although this is only in the spec and not exposed in the API.

document.createTransition() becomes
document.createViewTransition()

This is the API developers use to create a transition between states in an SPA.

Rationale:

  • Although it's longer, it removes the ambiguity with CSS transitions.

Example

Taking the slide-from-the-side example from the breakout at TPAC:

Old:

::page-transition-outgoing-image(root) {
  animation: 500ms ease-out both slide-to-left;
}

::page-transition-incoming-image(root) {
  animation: 500ms ease-out both slide-from-right;
}

New:

::view-before(root) {
  animation: 500ms ease-out both slide-to-left;
}

::view-after(root) {
  animation: 500ms ease-out both slide-from-right;
}

(I've omitted the keyframes since they're the same in both)

Resulting pseudo-tree

::view-root
├ ::view(custom-ident)
|  └─ ::view-image-group(custom-ident)
|     ├─ ::view-before(custom-ident)
|     └─ ::view-after(custom-ident)
└ ::view(different-ident)
   └─ ::view-image-group(different-ident)
      ├─ ::view-before(different-ident)
      └─ ::view-after(different-ident)

(thanks @mirisuzanne!)

Activity

  1. bramus commented on Sep 24, 2022

    @bramus
  2. jakearchibald commented on Sep 24, 2022

    @jakearchibald
    Author
  3. ydaniv commented on Sep 25, 2022

    @ydaniv
    Member

    View may be confusing since there's already ViewTimeline and its semantics are quite different - closer to those of viewport and viewbox.
    And if considering view() it may also be relevant to consider #7587.

    I guess a more accurate name would be "Cross Element Transition", but that isn't helping with the brevity part 🙂
    Perhaps something like cross-transition? (or x-transition?)

  4. tbondwilkinson commented on Sep 26, 2022

    @tbondwilkinson

    I am quite fond the name "view"!

    view-name sounds like it's the name of the view, but really it's a "part" of the overall "view" transition.

    Just so I understand, why is there a need to use a new tagging system, rather than reusing one of the existing tagging systems (class, id)? I assume it's hard to support general selectors in psuedoelements here, but still wondering whether with this new DOM structure being represented in pseudoelements, rather you really do need some sort of selector syntax for that. I believe this was proposed elsewhere, I forget what the response was.

    html::view(.header)
    

    I do like the shorter names, but naming things just ::view does lose the sense of transition. ::view alone sounds like it could be static, like ::backdrop rather than something ephemeral and specific to a transition. Somewhere in between is ::view-transition

    Alternate to before and after is enter and exit, which are slightly shorter.

    Rather than view-before is a pseudoclass an option?

    ::view-transition(root):enter
    
  5. jakearchibald commented on Sep 26, 2022

    @jakearchibald
    ContributorAuthor

    @tbondwilkinson

    view-name sounds like it's the name of the view, but really it's a "part" of the overall "view" transition.

    view-part-name may be more accurate, but longer.

    Just so I understand, why is there a need to use a new tagging system, rather than reusing one of the existing tagging systems (class, id)?

    I don't think setting a class or an ID on an element means it should be a seperate part in an animated transition. That isn't what those things semantically mean. And with class especially, it would cause an explosion of layers, since it's extremely common for an element to have a class.

    It's common to want to differ the animation based on:

    • Viewport width
    • User preference (eg prefers-reduced-motion)
    • Cascade (like a class name on the root element may influence whether a descendant is a seperate part of an animation)

    This is trivial with CSS (@media, the cascade), but really really had to do with attributes.

    Besides, this is very much a 'design' feature, so it semantically fits better with CSS than DOM attributes. See also container-name and scroll-timeline-name.

    but still wondering whether with this new DOM structure being represented in pseudoelements, rather you really do need some sort of selector syntax for that. I believe this was proposed elsewhere, I forget what the response was.

    Yeah, we're working on a few options here. I'll create a separate issue for that. I'm waiting on Mozilla folks to review it, because I want to be sure I'm representing their proposal correctly. That shouldn't impact this naming change though.

    Rather than view-before is a pseudoclass an option?

    It would work, but I don't see the advantage. This would require ::view-transition(root) to match:

    • the root part
    • the root part's image group
    • the root part's before image
    • the root part's after image

    …and I don't see why you'd ever want to do that.

  6. mirisuzanne commented on Sep 26, 2022

    @mirisuzanne
    Contributor

    Bikeshedding overall name can keep happening - short is nice, and clear is also nice, and there's probably a balance worth finding.

    I'm also interested in the structure being represented. I know one of the alternatives we discussed at TPAC involved some sort of 'pseudo-element descendant combinators' to make that structure more clear, and I pushed back some on needing a whole new syntax for it. But it's true that the structure gets a bit lost in this variant.

    I think that the resulting pseudo-element tree is:

    ::view-root
    ├ ::view(custom-ident)
    |  └─ ::view-image-group(custom-ident)
    |     ├─ ::view-before(custom-ident)
    |     └─ ::view-after(custom-ident)
    └ ::view(different-ident)
       └─ ::view-image-group(different-ident)
          ├─ ::view-before(different-ident)
          └─ ::view-after(different-ident)
    

    My immediate instinct was to try and put some structure inside the functional notation somehow:

    ::view-root
    ├ ::view(custom-ident)
    |  └─ ::view(custom-ident image-group)
    |     ├─ ::view-image(custom-ident image-before)
    |     └─ ::view-image(custom-ident image-after)
    ...
    

    But looking at it, I'm not convinced that's a good path to take. Maybe the real gain I'm looking for here is just to associate the 'image group' with the 'before' and 'after' images a bit more clearly. Something like:

    ::view-root
    ├ ::view(custom-ident)
    |  └─ ::view-image-group(custom-ident)
    |     ├─ ::view-image-start(custom-ident)
    |     └─ ::view-image-end(custom-ident)
    ...
    

    or:

    ::view-root
    ├ ::view(custom-ident)
    |  └─ ::view-group(custom-ident)
    |     ├─ ::view-start(custom-ident)
    |     └─ ::view-end(custom-ident)
    ...
    

    So in the end, I like the direction you're going - and it maybe does just come down to a bit more bikeshedding. I kinda like start and end, since we already have before and after pseudos that mean something pretty different. But I don't feel strongly.

  7. tbondwilkinson commented on Sep 26, 2022

    @tbondwilkinson

    Just so I understand, why is there a need to use a new tagging system, rather than reusing one of the existing tagging systems (class, id)?

    Let me rephrase, why not have an opt-in to transitions and then reuse whatever class/id already exists on that element.

    <div id="foo"></div>
    
    #foo {
      view-transition: root;
    }
    

    Which leads to something like:

    ::view-transition(root #foo)::enter
    
  8. jakearchibald commented on Sep 26, 2022

    @jakearchibald
    ContributorAuthor

    @mirisuzanne

    I'm also interested in the structure being represented. I know one of the alternatives we discussed at TPAC involved some sort of 'pseudo-element descendant combinators' to make that structure more clear

    Yeah, I've got a whole other doc on that with all the options that I'd love your opinion on. I'm waiting on @emilio to review it first, because I want to make sure I've represented the shadow DOM pattern correctly & fairly.

    I think that the resulting pseudo-element tree is:

    ::view-root
    ├ ::view(custom-ident)
    |  └─ ::view-image-group(custom-ident)
    |     ├─ ::view-before(custom-ident)
    |     └─ ::view-after(custom-ident)
    └ ::view(different-ident)
       └─ ::view-image-group(different-ident)
          ├─ ::view-before(different-ident)
          └─ ::view-after(different-ident)
    

    Yep, that's correct

    I kinda like start and end, since we already have before and after pseudos that mean something pretty different. But I don't feel strongly.

    Hmm, start and end feel layout-positional to me (from align-content and co). I get what you mean about ::before and ::after though.

  9. mirisuzanne commented on Sep 26, 2022

    @mirisuzanne
    Contributor

    Hmm, start and end feel layout-positional to me (from align-content and co). I get what you mean about ::before and ::after though.

    Yeah, I agree that both have baggage. In my mind the start/end baggage is just a bit more distant, since it's not part of existing pseudo-classes? But it's maybe a small distinction.

  10. jakearchibald commented on Sep 26, 2022

    @jakearchibald
    ContributorAuthor

    Both are better than incoming and outgoing anyway

  11. SebastianZ commented on Sep 27, 2022

    @SebastianZ
    Contributor

    As others mentioned before, naming those pseudo-elements and the API just "view" might be too general and may lead to confusions with other features. Reading the initial renaming proposal, I immadiately thought: Why is "transition" not part of their names anymore when that's the whole point of this feature? And we are defining views that are transitioned, so maybe it should rather be "transition view"?
    So my take on that would be to always have transition-view-* as a prefix. I.e.

    page-transition-tag becomes view-name

    transition-view-name

    html::page-transition becomes html::view-root

    html::transition-view-root

    html::page-transition-container(header) becomes html::view(header)

    html::transition-view(header)

    html::page-transition-image-wrapper(header) becomes html::view-image-group(header)

    html::transition-view-image-group(header)

    html::page-transition-outgoing-image(header) and html::page-transition-incoming-image(header) become html::view-before(header) and html::view-after(header) respectively

    html::transition-view-before(header)
    html::transition-view-after(header)

    document.createTransition() becomes document.createViewTransition()

    document.createTransitionView()

    Note that I am totally aware that this makes the names mostly even longer than the original ones. Though I believe that clarity has higher priority than brevity.

    Sebastian

  12. fantasai commented on Sep 28, 2022

    @fantasai
    Collaborator

    Hi @jakearchibald! I love the thought that you put into this. It's maybe obvious, but I'm missing why ::view(header) and ::view-image-group(header) are two different elements? Can we combine them?

    I agree with @SebastianZ that we seem to have lost the transition aspect of the names, and maybe that's worth keeping somehow.

    If you want to use pseudo-element structure to represent the nesting, maybe something like:

    ::transition /* root */
    ::transition::view(header) /* group */
    ::transition::view(header)::old   /* outgoing image */
    ::transition::view(header)::new /* incoming  image */
    

    If not, then collapsing down the names:

    ::transition
    ::transition-view(header)
    ::transition-view-old(header)
    ::transition-view-new(header)
    
  13. jakearchibald commented on Sep 28, 2022

    @jakearchibald
    ContributorAuthor

    @fantasai

    It's maybe obvious, but I'm missing why ::view(header) and ::view-image-group(header) are two different elements? Can we combine them?

    Right now, every ::view(name) is a sibling in the view root, but we're pretty sure we'll add a feature to allow a ::view(name) to be nested in another ::view(name). We've got some vague docs for that here https://github.com/WICG/shared-element-transitions/blob/main/explainer.md#nested-transition-containers.

    In this model, the ::view-image-group(name) provides the blending isolation between the images, so nested :views don't get impacted by the blending.

    I agree with @SebastianZ that we seem to have lost the transition aspect of the names, and maybe that's worth keeping somehow.

    I'm not against that, but brevity kinda goes out the window. In some cases, like page-transition-tag to view-transition-name, it's getting longer.

    If you want to use pseudo-element structure to represent the nesting…

    I've got a separate analysis on that, but I'm waiting on @emilio to review it before I share it more widely. I want to make sure I'm representing the shadow DOM idea properly & fairly.

    If not, then collapsing down the names:

    ::transition
    ::transition-view(header)
    ::transition-view-old(header)
    ::transition-view-new(header)
    

    I like old and new for the image names!

    Are you ok with ::transition given that CSS transitions already exist, and this feature is unrelated (it uses CSS animations, not transitions)?

  14. 27 remaining items

  15. css-meeting-bot commented on Oct 26, 2022

    @css-meeting-bot
    Member

    The CSS Working Group just discussed Selector syntax for generated elements, and agreed to the following:

    • RESOLVED: Go with the Option 3 syntax.
    • RESOLVED: Name the function .startViewTransition()
    The full IRC log of that discussion <TabAtkins> Topic: Selector syntax for generated elements
    <TabAtkins> github: https://github.com//issues/7788
    <TabAtkins> vmpstr: We've discussed the names previously
    <TabAtkins> vmpstr: Two parts - what names do the pseudos have, and how to select them in CSS?
    <TabAtkins> vmpstr: Summarized in one of the later comments
    <vmpstr> https://github.com//issues/7788#issuecomment-1287309961
    <TabAtkins> vmpstr: some names that don't seem to have much discussion
    <TabAtkins> vmpstr: A lot focused on "images" vs "group/set/etc" for the wrapper element that has isolation on it
    <TabAtkins> vmpstr: don't think we have consensus
    <TabAtkins> vmpstr: But hoping we can resolve on the rest
    <TabAtkins> vmpstr: So, about selection, option 1 is full chaining
    <TabAtkins> vmpstr: Shows the whole structure of the pseudos
    <TabAtkins> vmpstr: option 2 is the same but with repetition removed from the nested names
    <TabAtkins> vmpstr: option 3 is we let all the elements hang off of the root, so you can select any of them directly without needing to navigate the nesting
    <TabAtkins> vmpstr: option4 is ::transition-part() which is similar syntactically to ::part() but otherwise resembles option 3
    <astearns> ack fantasai
    <TabAtkins> fantasai: I don't think the redundant chaining is a good idea, should eliminate it.
    <JakeA> q+
    <TabAtkins> fantasai: Either reduced chaining or direct attachment makes the most sense
    <TabAtkins> fantasai: I think (1) is unnecessarily terrible, 2 and 3 seem like best options
    <TabAtkins> fantasai: No strong opinion between those two
    <TabAtkins> fantasai: Slightly concerned in 2 when you add the subtree version of the transitions, will it make these longer or keep the same?
    <TabAtkins> fantasai: I think there was discussion about nesting inside of things, so if we reflect the full structure will it get longer?
    <TabAtkins> flackr: i don't think it will
    <TabAtkins> vmpstr: I think it will, if we do the full chaining
    <TabAtkins> khush: Yes, same as existing pseudos, you have to have the full chain (like ::before::marker isn't matched by ::marker)
    <miriam> q+
    <TabAtkins> [missed a clarification]
    <TabAtkins> fantasai: So I think that would be a reason to not go with 2
    <TabAtkins> vmpstr: So that leaves 3 as your pref?
    <TabAtkins> fantasai: Based on what I know so far, yes.
    <astearns> ack JakeA
    <TabAtkins> I also vote 3, fwiw
    <TabAtkins> JakeA: There was a proposal for a pseudo-descendant combinator which would let you skip some of the things in option 1 and 2
    <vmpstr> :>> old
    <smfr> q+
    <TabAtkins> JakeA: But with option 2 there's a worry there's an ambiguity - a short `::old` which is nicely short and contextual, suddenly becomes potentially clashing with other uses
    <astearns> ack miriam
    <astearns> q+
    <TabAtkins> miriam: I asked in the doc - on 4, is it possible to allow combinators within the function?
    <TabAtkins> miriam: i'm thinking about, "when you have old but not new, do something special" - can we attach that to a part-like syntax?
    <TabAtkins> astearns: Would that just come after the function?
    <TabAtkins> miriam: I was imagining it inside but mayb eit does work
    <TabAtkins> khush: Since this borrows the ::part() syntax, the keywords that go inside it are like class names.
    <JakeA> q+
    <astearns> ack smfr
    <TabAtkins> khush: we could add a new tag marking when something has just-old, just-new, or both, but you wouldn't be able to query arbitrary things yourself
    <astearns> ack astearns
    <TabAtkins> smfr: Can I use normal descendant selectors to address these elements?
    <TabAtkins> JakeA: No, not true for pseudos in general
    <vmpstr> TabAtkins: you can't use general descendant selectors into shadows
    <TabAtkins> smfr: seems bad to lose the ability to use familiar selector syntax
    <TabAtkins> TabAtkins: true for shadows too - all you ahve is ::part(), which loses structure
    <TabAtkins> smfr: can you write a selector that does do structure inside the shadow?
    <TabAtkins> TabAtkins: no
    <TabAtkins> smfr: unfortunate. Seems the nested double-colon things are unwieldy.
    <TabAtkins> fantasai: These things we're selecting, are they elements or are they pseudos?
    <TabAtkins> fantasai: Can you pull them out and change their styles with JS?
    <TabAtkins> JakeA: Per previous resolution, they're pseudo-elements.
    <fantasai> html::view-transition(:root)
    <TabAtkins> fantasai: What about something like option 4 but rather than part-like with keywords, it takes a selector subset?
    <fantasai> html::view-transition(old)
    <fantasai> html::view-transition(.currenttransitionthingIlike new)
    <fantasai> html::view-transition(.currenttransitionthingIlike > new)
    <smfr> q+
    <miriam> +1 that's what I was trying to get at
    <TabAtkins> fantasai: So we'd take some subset of selectors, you can use the tree-querying selectors like :root or :first-child
    <JakeA> q-
    <TabAtkins> khush: So ::view-transition just gets you at the root node for these pseudos, then any selector that you can use today will traverse this tree?
    <TabAtkins> fantasai: Pretty much, yeah.
    <miriam> https://docs.google.com/document/d/1kW4maYe-Zqi8MIkuzvXraIkfx3XF-9hkKDXYWoxzQFA/edit?disco=AAAAiKGTYoY
    <TabAtkins> JakeA: In this model where would I be saying I"m targeting the "new" of the header?
    <TabAtkins> ::view-transition(images.header > old)
    <fantasai> html::vt(.header new) /* if flat */
    <fantasai> html::vt(.header > image-set > new) /* if complicated */
    <TabAtkins> JakeA: a pseudo with a class name seems different but i don't hate it...
    <TabAtkins> (I think this is a good idea actually.)
    <astearns> ack smfr
    <astearns> ack fantasai
    <Zakim> fantasai, you wanted to ask about subtree selectors
    <JakeA> I like that it retains the structure
    <ydaniv> or ::view-transition(::new) ?
    <TabAtkins> smfr: The things being styled are the snapshots, right?
    <TabAtkins> vmpstr: yes
    <fantasai> fantasai^: I don't know if it's a good idea, but it's an idea
    <TabAtkins> smfr: Would it be possible to describe these by pointing to the element being snapshotted?
    <TabAtkins> JakeA: I tried to create a proposal based on that, but in many cases you're animating somethign that's no longer there
    <TabAtkins> JakeA: So trying to target somethign that might be gone (or which the matched els have changed) is weird
    <TabAtkins> smfr: Seems like you'd snapshot
    <TabAtkins> JakeA: IN a multi-page transition you'd be mixing styles from the old and new page, whichi gets tricky.
    <TabAtkins> JakeA: The model is for multi-page the incoming page gets to control the animation
    <emilio> q+
    <TabAtkins> smfr: Yeah I see that case is hard
    <TabAtkins> smfr: Is multi-page sitll a realistic goal?
    <TabAtkins> JakeA: Yeah, I'm working on it right now
    <TabAtkins> smfr: Still seems the from and to page have to have a close enough appearance, so maybe it's not too bad to require them to have close structures
    <vmpstr> q?
    <TabAtkins> flackr: The containers around the snapshot don't belong to either starting or ending element
    <astearns> ack emilio
    <TabAtkins> JakeA: I think smfr was suggesting a pseudo targeting that
    <TabAtkins> [missed what that actually meant]
    <TabAtkins> emilio: Is the idea that the pseudos are still on the root?
    <TabAtkins> vmpstr: Yes, if you tag elements in your page they get flattened to a list attached to the root
    <TabAtkins> vmpstr: In the later proposal instead of flattening we'd retain the hierarchy from the DOM, but the structure would still attach to the root element
    <TabAtkins> emilio: So these pseudos will still only be usable from the root
    <TabAtkins> vmpstr: yes
    <TabAtkins> emilio: I"m not a fan of "arbitrary selectors", mostly becuase we've already seen it's weird that we need extra containers for wrappers and isolation
    <TabAtkins> emilio: So once we expose the structure we can't change that ever
    <TabAtkins> emilio: maybe that's ok
    <JakeA> q+
    <TabAtkins> TabAtkins: Several of the syntaxes already epxose the structure, and I think in general styling will expose the structure.
    <TabAtkins> TabAtkins: Don't think the structure can be changed without a mode switch
    <TabAtkins> emilio: say you have a new transition type that needs a new wrapper
    <TabAtkins> emilio: stuff generally keeps working
    <fantasai> +1 to emilio's point
    <TabAtkins> khush: I was expecting one thing that would be consistent is that the only thing that affects the structure is view-transition-name
    <TabAtkins> khush: So if you ahve two doms and have the same tag applied, you'll consistnetly get the same structure
    <TabAtkins> khush: So if the structure changes I expect it's from the author changing something
    <TabAtkins> khush: so was emilio talkinga bout changing the structure even if the authors don't change anything?
    <TabAtkins> emilio: Yeah, if you want to expose a new transition type with a differetn structure
    <TabAtkins> q+ about this
    <TabAtkins> ack about
    <TabAtkins> ack this
    <TabAtkins> q+
    <astearns> ack JakeA
    <TabAtkins> JakeA: The reason we added the image wrapper was to give us some leeway for this nested model
    <TabAtkins> JakeA: otherwise we could use the container itself for the isolation
    <TabAtkins> JakeA: We didn't think we could add structure later without breaking author styles
    <TabAtkins> JakeA: There's also Miriam's point about "only old" or "only new" wanting a different animation
    <TabAtkins> JakeA: So if we use :only-child for that that does lock us into some structure
    <vmpstr> TabAtkins:
    <astearns> ack TabAtkins
    <fantasai> scribe+
    <fantasai> TabAtkins: Concern that emilio has, not necessarily that we change structure of existing transitions, but if we add a new type that needs a new structure
    <fantasai> TabAtkins: concern would be if you have styles generically applying to old styles, and add new transition type, something might break
    <fantasai> TabAtkins: don't think we should be concerned; if you make a new type of transition, make new styles
    <fantasai> TabAtkins: also not sure any existing styling would work properly under a new structure, might implicitly depend on it
    <fantasai> TabAtkins: so not guaranteed to work. And it's a new feature anyway
    <fantasai> TabAtkins: so I don't think this is a very strong argument
    <astearns> ack fantasai
    <khush> q?
    <JakeA> q+
    <TabAtkins> fantasai: say, picking out the old from a transition is a little tricky
    <TabAtkins> fantasai: if you want the old header transition, you ahve to pipe thru the whole structure and use child selectors
    <TabAtkins> fantasai: if the header has a nested icon also transitioning (assuming nested transitions) you can't just generically address olds
    <TabAtkins> fantasai: So using the selector syntax has more power but does require a little extra work
    <khush> q+
    <TabAtkins> fantasai: So my inclination is option 3, and if at some point we need to add more structure we can do 4 with selectors
    <fremy> +1, I think this is the type of things we can add later
    <TabAtkins> fantasai: But I think ahving a pseudo that doe sthe lookup cleanly seems fine anyway
    <astearns> zakim, close queue
    <Zakim> ok, astearns, the speaker queue is closed
    <astearns> ack khush
    <argyle> q+
    <astearns> ack JakeA
    <TabAtkins> TabAtkins: I was assuming that everything under a tag would be tagged with it, so `old.header` would work instead of needing `.header > images > old`
    <TabAtkins> khush: +1 to option 3, dealing with selectors would just be hard
    <TabAtkins> khush: Also yes, we do tag every element with the given tag
    <TabAtkins> JakeA: We should capture the selector idea in the issue for later, tho
    <TabAtkins> argyle: Somethign I like about 4 is it's clear what's being selected
    <TabAtkins> argyle: Since 3 is nice, I suggest instead of using a pseudo-element function we just use a descendant combinator
    <fantasai> I think argyle is asking for something like html::view-transition old.header
    <fantasai> ?
    <fremy> @argyle: do you mean `::view-transition #id` ?
    <TabAtkins> yeah adam is asking for elika's idea, just not inside the parens
    <TabAtkins> vmpstr: The "foo" in option 3 is the tag of the container itself, it's not like :has()
    <JakeA> seems ambiguous with descendant combinators?
    <fremy> JakeA: yeah, I think the idea is that it's like a descendant in the "view-transition" tree
    <TabAtkins> argyle: Okay, I was misunderstadning how the targeting worked, the pseudo-element is targeting the pseudo in question
    <fremy> fantasai, ah yes, good idea. I'm falling for the autocomplete...
    <Sebastian_Zartner> +1
    <TabAtkins> astearns: So proposal is to go with option 3, leaving the possibility of future selector power
    <TabAtkins> RESOLVED: Go with the Option 3 syntax.
    <Sebastian_Zartner> +1 on option 3 with option 4 for future extensions
    <TabAtkins> vmpstr: are the names part of this resolution, or do we need to discuss those separately?
    <TabAtkins> astearns: This is the CSSWG, we'll definitely discuss names again. But go with what's in the issue for now.
    <TabAtkins> vmpstr: Also the JS api name to start a transition isn't good.
    <TabAtkins> vmpstr: Proposal is .transitionView()
    <vmpstr> document.transitionView()
    <TabAtkins> khush: Took inspriation from element.animate()
    <TabAtkins> astearns: Is there an issue open for this?
    <TabAtkins> vmpstr: it's part of this issue
    <TabAtkins> smfr: "transition view" reads like a noun
    <TabAtkins> smfr: startViewTransition()?
    <fantasai> +1 to startTransitionView
    <TabAtkins> JakeA: createViewTransition() was what we had before
    <fantasai> or startViewTransition
    <TabAtkins> ydaniv: There's a separate issue about whether we should start by default
    <TabAtkins> astearns: Objections to .startViewTransition() ?
    <TabAtkins> RESOLVED: Name the function .startViewTransition()
  16. jakearchibald commented on Oct 26, 2022

    @jakearchibald
    ContributorAuthor

    @fantasai and @mirisuzanne suggested a syntax like this:

    html::view-transition(.header new) {
      …
    }

    Where the bit within view-transition() would allow for a complex selector where the view-transition-name is 'turned into' a class name, and the parts of the structure are 'turned into' tag names. So the above is selecting 'new' parts within the container with view-transition-name of header.

  17. FremyCompany commented on Oct 26, 2022

    @FremyCompany
    Contributor

    Note that if we want to allow complex selectors like this in the future, but not in the first version, this is possible if we change the syntax to allow ID selectors only:

    html::view-transition(#group-foo) {
      …
    }
    html::view-transition(#old-foo) {
      …
    }
    html::view-transition(#new-foo) {
      …
    }

    (where the ids are auto-generated based on the syntax that would be used in proposal 4)

    That enable us to go for more complex selectors later, if there is a demand, without adding much difficulty for authors (only add one pound symbol in the function).

    Of course, if we are quite sure we won't need complex selectors, this is moot. Just a random thought.

  18. khushalsagar commented on Oct 26, 2022

    @khushalsagar
    Member

    Filed #7960 since we didn't get to resolve on all the names today.

    @jakearchibald regarding the syntax you mentioned, when you say tag names are you drawing a parallel with element tag like img. So the proposal there would be equivalent to a selector like this in CSS:

    .class-foo img {
      ...
    }

    I assumed this proposal is about allowing existing selector patterns as the function argument but the above is not valid syntax today. Maybe I misunderstood the proposal.

    @FremyCompany that's an interesting thought. ID is not a good concept though since it'll be unique per pseudo-element and we do want to allow selecting all containers for example. Classes is better. But I'm a little wary of supporting all complex selectors there.

    The use-cases for more complex selectors we've seen have been about rules which are conditional based on the DOM structure. Could we do that by allowing a subset of existing pseudo-classes on pseudo-elements. So something like html::view-transition-old(foo):only-child if the styles are conditional based on there being a pair of images vs an exit transition (only old content).

  19. tabatkins commented on Oct 26, 2022

    @tabatkins
    Member

    Yes, the idea suggested by fantasai/miriam is that we expose the structure of the pseudo tree directly, with the names mapped to element names and the tags mapped to classes. So html::view-transition(.foo old) matching an "old" image who is a descendant of a "foo"-tagged container or image-group. Then you could write html::view-transition(old.foo:only-child) to get an old that doesn't have a new.

  20. mirisuzanne commented on Nov 3, 2022

    @mirisuzanne
    Contributor

    I'll note that our suggestion doesn't rely specifically on the specific mapping of class/element syntax, but that provides a good example. Whatever the selector-syntax mapping (@FremyCompany's suggestion of IDs might make more sense), the goal is just to allow compound/complex selectors in the function.

    One reason for that might be exposing the hierarchy. The more important goal in my mind was the ability to differentiate what happens in these three instances:

    1. There is only a new image.
    2. There is only an old image.
    3. There are both old and new images.

    The solution mentioned a few times for that is using :only-child/:not(:only-child) on the element in question. I assume that solution is also possible with the current proposal?

    html::view-transition-old(*):only-child {
      /* this is a default exit animation */
    }
  21. jakearchibald commented on Nov 3, 2022

    @jakearchibald
    ContributorAuthor

    @mirisuzanne I think we need to make that work. And if it can't be :only-child, we should add something view-transition-specific to do the same thing.

  22. khushalsagar commented on Nov 3, 2022

    @khushalsagar
    Member

    I think we should be able to make the :only-child pseudo-class work. I figured pseudo-classes on pseudo-elements would already be a supported concept. For instance, before:hover seems like a valid use-case. But I just tried and it's not supported. Maybe there is an implementation complexity associated with supporting pseudo-classes on pseudo-elements in general that I'm missing.

  23. jakearchibald commented on Nov 3, 2022

    @jakearchibald
    ContributorAuthor

    I think it's tricky because what does ::before:only-child mean? We might need to allow-list which pseudos can use :only-child.

  24. khushalsagar commented on Nov 10, 2022

    @khushalsagar
    Member

    The spec edits for this issue have landed. I started a different one to capture the use-case discussed above.

    In case I missed anything else on this issue which still needs discussion please file another issue for it.

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