Re: [csswg-drafts] [css-view-transitions-2] [scoped] Clarify the ::v-t box and stacking context position relative to the scope (#12324)

> 3. Extend the semantics of `view-transition-group` so that `contain` generates a `::view-transition-group-children()` pseudo even if the element has `view-transition-name: none` and is therefore not itself a participant in the transition.
> 
> […]
> 
> The developer still has the option to create a scope that is not self-participating, by setting `view-transition-name: none`. Such a scope would generate a `::v-t-group-children` but not a `::v-t-group` or a `::v-t-old` or a `::v-t-new`.
> 
> The developer can also, if they want, set `view-transition-group: none` on the scope, to suppress the `::v-t-group-children` and override the default nesting behavior in our proposal.

We discussed this a bit more internally and I pointed out that this has some weird side-effects on the pseudo-tree that needs to be generated. Specifically, if the scope has no `view-transition-name`, then:

- What would go inside of the parenthesis of `::view-transition-group-children()`?
- Where does this `::view-transition-group-children()` pseudo get placed in the tree? Directly under the `::view-transition` instead of under its `::view-transition-group()`?

I mean, this seems weird:

```
#element
  └─ ::view-transition
      └─::view-transition-group-children(⁉️)
         ├─ ::view-transition-group(child1)
         │   └─ ::view-transition-image-pair(child1)
         │       ├─ ::view-transition-old(child1)
         │       └─ ::view-transition-new(child1)
         └─ ::view-transition-group(child2)
             └─ ::view-transition-image-pair(child2)
                 ├─ ::view-transition-old(child2)
                 └─ ::view-transition-new(child2)
```

---

A solution that doesn’t have this side-effect is to **always** capture the scope as part of a scoped view transition _(thus: the scope is always self-participating)_, but give authors a way to indicate that they only want to capture its dimensions – so without its pixels/textures.

When only capturing the dimensions, this results in a more consistent pseudo-tree:
- The `::view-transition-group(root)` for that element is always generated
- There is a `::view-transition-group-children(root)` for its children that were captured (if any)
- The `::view-transition-image-pair` becomes conditional, without affecting the rest.

In practice, the pseudo-tree would look like this:

- When capturing dimensions + texture (default behavior):

    ```
    #element
      └─ ::view-transition
          └─ ::view-transition-group(root)
              ├─ ::view-transition-image-pair(root)
              │  ├─ ::view-transition-old(root)
              │  └─ ::view-transition-new(root)
              └─::view-transition-group-children(root)
                 ├─ ::view-transition-group(child1)
                 │   └─ ::view-transition-image-pair(child1)
                 │       ├─ ::view-transition-old(child1)
                 │       └─ ::view-transition-new(child1)
                 └─ ::view-transition-group(child2)
                     └─ ::view-transition-image-pair(child2)
                         ├─ ::view-transition-old(child2)
                         └─ ::view-transition-new(child2)
    ```

- When capturing only the dimensions:

  ```
  #element
    └─ ::view-transition
        └─ ::view-transition-group(root)
            └─::view-transition-group-children(root)
               ├─ ::view-transition-group(child1)
               │   └─ ::view-transition-image-pair(child1)
               │       ├─ ::view-transition-old(child1)
               │       └─ ::view-transition-new(child1)
               └─ ::view-transition-group(child2)
                   └─ ::view-transition-image-pair(child2)
                       ├─ ::view-transition-old(child2)
                       └─ ::view-transition-new(child2)
  ```

Additionally, when only capturing the dimensions, the real (new) element still gets drawn underneath the scoped transition pseudo-tree.

---

There is still an open question on how authors can do this opt-in.

Some options we discussed:

1. Give authors a CSS property to indicate this behavior.
    
      ```css
      #element {
        view-transition-capture-mode: dimensions; /* initial value: normal */
      }
      ```
   
    I believe this `view-transition-capture-mode: dimensions` would also prove itself useful for other parts of View Transitions (not linked to scoped transitions) such as in-place element transitions, making https://www.bram.us/2025/05/15/view-transitions-border-radius-revisited/#a-simpler-approach more easier for authors to do.
  
    Note that for this to work, the UA would generate this stylesheet whenever you start a Scoped View Transition:
  
    ```css
    vt-scope {
      view-transition-name: root !important;
      view-transition-group: contain;
    }
    
    /* Conditional. Only gets set if the scope’s overflow style is not visible */
    vt-scope::view-transition-group-children(root) {
      overflow: clip;
    }
    ```
    
    The `!important` might catch your eye there, but I think this is warranted here because you always want the scope to be captured.
    
    The effect on Steve’s proposal would be that bullet 3 in the list becomes this:
    
    > 3. User-agent style sets `view-transition-group: root !important` on the scope during its transition. Authors can opt-out from capturing the pixels of the scope by declaring `view-transition-capture-mode: dimensions;` on it.
  
2. The same as 1, but do the opt-in from JS

      ```js
      document.querySelector('#element').startViewTransition({
          callback: () => { … },
          rootCapture: "dimensions-only",
      );
      ```
    
    This feels pretty limited, as it’s a flag that only works for Scoped Transitions.

3. Automagically do this when authors set `view-transition-name: none` on the scope root in their author stylesheet.
     
    Personally I find this a bit too magical, because authors are indicating that they don’t want to capture it, yet somehow it would still show up in the pseudo-tree.

4. _[insert-your-idea-here]_



-- 
GitHub Notification of comment by bramus
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12324#issuecomment-3636012365 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Wednesday, 10 December 2025 08:50:46 UTC