Strange transition using anchor positioning and popovers

I am using anchor positioning (the solution can only be described as 'interesting') to position some 'toast' popovers (top-layer), with a transition (translation) using allow discrete behaviour. This works fine for transitioning in to view. However, when the popover is being hidden, the element suddenly loses its anchoring halfway through the transition. Codepen link: https://codepen.io/reuseaux/pen/pvJOzaJ
6 Replies
lko
lko3mo ago
Most of the issue was setting inset only when they were :popover-open, so when you close them, they're not :popover-open anymore, so they don't have inset anymore so they jump somwhere in the page. If you just remove the :popover-open from your selectors:
&:nth-child(1 of .toast) {
anchor-name: --toast-1;
inset: auto 1rem 1rem auto;
}

&:not(:nth-child(1 of .toast)) {
anchor-name: --toast;
position-anchor: --toast;
inset: auto anchor(right) calc(anchor(top) + 1rem) auto;
}

&:nth-child(2 of .toast) {
position-anchor: --toast-1;
}
&:nth-child(1 of .toast) {
anchor-name: --toast-1;
inset: auto 1rem 1rem auto;
}

&:not(:nth-child(1 of .toast)) {
anchor-name: --toast;
position-anchor: --toast;
inset: auto anchor(right) calc(anchor(top) + 1rem) auto;
}

&:nth-child(2 of .toast) {
position-anchor: --toast-1;
}
It will work perfecty (but only for the first popover), the second one, since its position is based off the first one, when the first one disappears from the dom, the second one does't know where to place itself anymore, so it breaks To fix this I haven't tried, but I think you can just use a --count or maybe a sibling-index or something like that. But maybe i'll still create a div, that is positioned at the bottom right of the screen, and use that as a position-area, I don't know if it will work, but I don't see why it shouldn't
reüseaux
reüseauxOP3mo ago
Thanks for the reply; I have managed to fix the problem (no 'reference' div needed!), and it is much simpler than before.
inset: auto 1rem 1rem auto;
anchor-name: --toast;

&:not(:nth-child(1 of .toast:popover-open)) {
position-anchor: --toast;
bottom: calc(anchor(top) + 1rem);
}
inset: auto 1rem 1rem auto;
anchor-name: --toast;

&:not(:nth-child(1 of .toast:popover-open)) {
position-anchor: --toast;
bottom: calc(anchor(top) + 1rem);
}
This seems to be working now, though I have to say I don't know why I didn't do this to start with, and why I decided to use multiple different anchor-name properties!
lko
lko3mo ago
Wait, why is it working? I haven't played with anchor positioning that much But shouldn't the popover 2 and 3 be stacked on top of each other? Why are they not relative to the first toast? It's the only one that has an anchor-name and the other 2 have a position-anchor set to the first one, what am I missing here?
reüseaux
reüseauxOP3mo ago
The anchor-name: --toast; property is set for all .toast elements, not just the first one. I'm not actually sure how it is worked out which --toast anchor each subsequent toast is anchored to (e.g. why the third one is anchored to the second one not the first one). I'll see if I can find out how that happens.
reüseaux
reüseauxOP3mo ago
Found it... From MDN docs (https://developer.mozilla.org/en-US/docs/Web/CSS/anchor-name)
If multiple anchor elements have the same anchor name set on them, and that name is referenced by the position-anchor property value of a positioned element, that positioned element will be associated with the last anchor element with that anchor name in the source order.
MDN Web Docs
anchor-name - CSS | MDN
The anchor-name CSS property enables defining an element as an anchor element by giving it one or more identifying anchor names. Each name can then be set as the value of a positioned element's position-anchor property to associate it with the anchor.
lko
lko3mo ago
Oh right, I missed it, for some reason I saw that you set anchor-name only on the first one, now it makes sense, thank you

Did you find this page helpful?