You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[css-view-transitions-1] Enforce ::view-transition to be fixed position #8505
The ::view-transition pseudo-element is positioned relative to the snapshot root outlined in the spec here irrespective of the value of its position property. This was resolved in #7859.
It is also meant to be the containing block for its child pseudo-elements, the ::view-transition-group, clarified in the spec here. This is done by UA CSS setting its position property to fixed.
It's unclear what should happen if developer CSS modifies the position value for this element. We don't have any developer use-case where that's needed. Also the transform value computed by the UA and set on ::view-transition-group pseudo-elements is in the snapshot root's coordinate space. This relies on these elements being positioned relative to ::view-transition which itself uses snapshot root as its containing block.
The proposal is to state that the position value for ::view-transition always computes to fixed. I'd also be open to using absolute since its containing block is not the ICB and the desired behaviour is to make it a containing block for descendants. This is similar to what's done for top layer elements, spec'd here.
I'm fine with either of these - the positioning itself is basically a magic abspos. I guess I lean slightly toward absolute just because semantically it's tied to the document (ICB) rather than the viewport. But if there's other reasons to prefer one over the other I'm fine with that.
The position property on any element can have 2 side-effects:
It determines whether the element is out of flow and what it's containing block is. Even though ::view-transition's ancestor in the DOM hierarchy is its originating element, a.k.a the documentElement, we want it to be positioned relative to the the snapshot root. So the spec states that its containing block is always the snapshot root.
There is no use-case where an author would want to change that. In fact it would be odd to change it since the transform computed for ::view-transition-group elements is relative to the snapshot root.
It determines whether the element itself is a containing block for its descendants. The position: fixed rule in UA CSS on ::view-transition makes it a containing block for all its ::view-transition-group child pseudo-elements.
It's unclear what happens if the author changes ::view-transition to position: static. My read of the explanation here is that we'd walk up the ancestor chain until we find a positioned ancestor which will be the root element, so we'd end up with ICB instead of snapshot root. Which is again odd because the coordinate space based on which UA computes transforms for these is the snapshot root.
So the proposal here:
Enforce that position: fixed in UA CSS for ::view-transition is !important so authors can't override it. There is no use-case for them to do it now anyway. The only containing block above ::view-transition is the snapshot root. And if they want some child to be positioned relative to that, they can use position: fixed for it.
This avoids the need for another special rule for how we select the containing block if authors set position to static for ::view-transition.
This also means that position: fixed on view-transition pseudos means their containing block is going to be ::view-transition.
The CSS Working Group just discussed [css-view-transitions-1] Enforce ::view-transition to be fixed position, and agreed to the following:
RESOLVED: Define "snapshot CB" as the current snapshot root rect, give it ICB behaviors so it captures all elements (preventing them from going higher)
The full IRC log of that discussion
<TabAtkins> (vlad and khush are beign eaten by the AI)
<TabAtkins> vmpstr: We currently have a ::view-transition pseudo, the root of the whole VT pseudo-tree.
<TabAtkins> vmpstr: It has fixpos, and uses snapshot root as the contining block
<TabAtkins> vmpstr: We'd like to make fixpos unchangeable, via UA !important
<TabAtkins> vmpstr: Because we want the root pseudo to be a containing block to all other pseudos
<emilio> q+
<TabAtkins> vmpstr: If we don't have that, and author can change it, we'd have to figure out what the VT pseudos *should* use. Haven't found any use-case for it, so propose to enforce it
<astearns> ack emeyer
<astearns> ack emilio
<TabAtkins> emilio: I think it's fine, but do you also want to ensure you're a containing block for other fixpos children?
<TabAtkins> vmpstr: Does fixpos not contain fixpos?
<TabAtkins> TabAtkins: No
<TabAtkins> vmpstr: Okay then we'd also like it to be a fixpos containing block for its descendants.
<TabAtkins> emilio: Okay can do that in a few ways, or with magic. Like a no-op filter.
<TabAtkins> emeyer: Maybe just say it happens.
<TabAtkins> s/emeyer/emilio/
<TabAtkins> vmpstr: I'd say UA magic is fine, the structure of the tree is also unchangeable
<astearns> ack fantasai
<TabAtkins> fantasai: Would it make sense, instead, to define that the VT tree is contained by the snapshot root?
<TabAtkins> fantasai: In the same way the rest of the doc is contained by the ICB?
<TabAtkins> fantasai: LIke, you can't position anything based on higher than the ICB, we can say the same for the snapshot root for VT pseudos
<TabAtkins> fantasai: So if you change the position of VT, it'll still be laid out in the snapshot root, and children will still use the snapshot root as well, as normal
<TabAtkins> fantasai: So it basically lives in its own layout tree
<TabAtkins> vmpstr: I think.... that's fine. We basically just want to avoid going to the ICB in some cases
<TabAtkins> vmpstr: But as long as the CB chain stops at the snapshot root, that's fine
<TabAtkins> fantasai: Taht's my suggestion then, I might call it the "snapshot containing block" and define it similarly to ICB (capturing abspos, fixpos, etc)
<TabAtkins> astearns: Then we're not saying anything particular about the position value for the top VT pseudo?
<TabAtkins> fantasai: Right
<TabAtkins> fantasai: If you position:static, it'll be laid out as a block inside the snapshot CB
<TabAtkins> astearns: So proposed res is we define "snapshot containing block" for the VT pseudo-els, to get the effect we're looking for in this issue.
<TabAtkins> vmpstr: Defining it to be the snapshot root
<TabAtkins> fantasai: Yeah, rename "snapshot root" to snapshot CB and clarify it behaves as the ICB.
<TabAtkins> +
<TabAtkins> +1
<TabAtkins> astearns: Objections?
<TabAtkins> khush: Right now spec defines snapshot root to be "the rect that the viewport would be if all retractable UI is hidden"
<emeyer> TabAtkins: Containing block is already a rectangle
<emeyer> …You can literally say this is the CB
<TabAtkins> khush: So when we snapshot the root, we'll capture that rect as the snapshot CB
<TabAtkins> RESOLVED: Define "snapshot CB" as the current snapshot root rect, give it ICB behaviors so it captures all elements (preventing them from going higher)
Activity
tabatkins commentedon Feb 28, 2023
I'm fine with either of these - the positioning itself is basically a magic abspos. I guess I lean slightly toward
absolutejust because semantically it's tied to the document (ICB) rather than the viewport. But if there's other reasons to prefer one over the other I'm fine with that.khushalsagar commentedon Apr 6, 2023
Summarizing an offline discussion on this.
The
positionproperty on any element can have 2 side-effects:It determines whether the element is out of flow and what it's containing block is. Even though
::view-transition's ancestor in the DOM hierarchy is its originating element, a.k.a thedocumentElement, we want it to be positioned relative to the the snapshot root. So the spec states that its containing block is always the snapshot root.There is no use-case where an author would want to change that. In fact it would be odd to change it since the transform computed for
::view-transition-groupelements is relative to the snapshot root.It determines whether the element itself is a containing block for its descendants. The
position: fixedrule in UA CSS on::view-transitionmakes it a containing block for all its::view-transition-groupchild pseudo-elements.It's unclear what happens if the author changes
::view-transitiontoposition: static. My read of the explanation here is that we'd walk up the ancestor chain until we find a positioned ancestor which will be the root element, so we'd end up with ICB instead of snapshot root. Which is again odd because the coordinate space based on which UA computes transforms for these is the snapshot root.So the proposal here:
position: fixedin UA CSS for::view-transitionis!importantso authors can't override it. There is no use-case for them to do it now anyway. The only containing block above::view-transitionis the snapshot root. And if they want some child to be positioned relative to that, they can useposition: fixedfor it.This avoids the need for another special rule for how we select the containing block if authors set
positiontostaticfor::view-transition.This also means that
position: fixedon view-transition pseudos means their containing block is going to be::view-transition.css-meeting-bot commentedon Apr 12, 2023
The CSS Working Group just discussed
[css-view-transitions-1] Enforce ::view-transition to be fixed position, and agreed to the following:RESOLVED: Define "snapshot CB" as the current snapshot root rect, give it ICB behaviors so it captures all elements (preventing them from going higher)The full IRC log of that discussion
<TabAtkins> (vlad and khush are beign eaten by the AI)<TabAtkins> vmpstr: We currently have a ::view-transition pseudo, the root of the whole VT pseudo-tree.
<TabAtkins> vmpstr: It has fixpos, and uses snapshot root as the contining block
<TabAtkins> vmpstr: We'd like to make fixpos unchangeable, via UA !important
<TabAtkins> vmpstr: Because we want the root pseudo to be a containing block to all other pseudos
<emilio> q+
<TabAtkins> vmpstr: If we don't have that, and author can change it, we'd have to figure out what the VT pseudos *should* use. Haven't found any use-case for it, so propose to enforce it
<astearns> ack emeyer
<astearns> ack emilio
<TabAtkins> emilio: I think it's fine, but do you also want to ensure you're a containing block for other fixpos children?
<TabAtkins> vmpstr: Does fixpos not contain fixpos?
<TabAtkins> TabAtkins: No
<TabAtkins> vmpstr: Okay then we'd also like it to be a fixpos containing block for its descendants.
<TabAtkins> emilio: Okay can do that in a few ways, or with magic. Like a no-op filter.
<TabAtkins> emeyer: Maybe just say it happens.
<TabAtkins> s/emeyer/emilio/
<TabAtkins> vmpstr: I'd say UA magic is fine, the structure of the tree is also unchangeable
<astearns> ack fantasai
<TabAtkins> fantasai: Would it make sense, instead, to define that the VT tree is contained by the snapshot root?
<TabAtkins> fantasai: In the same way the rest of the doc is contained by the ICB?
<TabAtkins> fantasai: LIke, you can't position anything based on higher than the ICB, we can say the same for the snapshot root for VT pseudos
<TabAtkins> fantasai: So if you change the position of VT, it'll still be laid out in the snapshot root, and children will still use the snapshot root as well, as normal
<TabAtkins> fantasai: So it basically lives in its own layout tree
<TabAtkins> vmpstr: I think.... that's fine. We basically just want to avoid going to the ICB in some cases
<TabAtkins> vmpstr: But as long as the CB chain stops at the snapshot root, that's fine
<TabAtkins> fantasai: Taht's my suggestion then, I might call it the "snapshot containing block" and define it similarly to ICB (capturing abspos, fixpos, etc)
<TabAtkins> astearns: Then we're not saying anything particular about the position value for the top VT pseudo?
<TabAtkins> fantasai: Right
<TabAtkins> fantasai: If you position:static, it'll be laid out as a block inside the snapshot CB
<TabAtkins> astearns: So proposed res is we define "snapshot containing block" for the VT pseudo-els, to get the effect we're looking for in this issue.
<TabAtkins> vmpstr: Defining it to be the snapshot root
<TabAtkins> fantasai: Yeah, rename "snapshot root" to snapshot CB and clarify it behaves as the ICB.
<TabAtkins> +
<TabAtkins> +1
<TabAtkins> astearns: Objections?
<TabAtkins> khush: Right now spec defines snapshot root to be "the rect that the viewport would be if all retractable UI is hidden"
<emeyer> TabAtkins: Containing block is already a rectangle
<emeyer> …You can literally say this is the CB
<TabAtkins> khush: So when we snapshot the root, we'll capture that rect as the snapshot CB
<TabAtkins> RESOLVED: Define "snapshot CB" as the current snapshot root rect, give it ICB behaviors so it captures all elements (preventing them from going higher)
Rename snapshot-root to snapshot containing block
Rename snapshot-root to snapshot containing block
Rename snapshot-root to snapshot containing block
[css-view-transitions-1] Rename snapshot-root to snapshot containing …
[css-view-transitions-1] Use correct Snapshot Containing Block label …
[css-view-transitions-1] Use correct Snapshot Containing Block label …