Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-anchor-1] Tree-scoped references don't play nicely with transition styles #8180

Closed
tabatkins opened this issue Dec 2, 2022 · 7 comments

Comments

@tabatkins
Copy link
Member

A tree-scoped reference (such as the anchor() function) captures what tree its stylesheet is in, so it can resolve the reference appropriately. But during a transition/animation, the intermediate styles are defined to live in a transition stylesheet in a separate origin from the rest of the page.

Combine this with the fact that the animated value of an inset property is, approximately, top: calc(start-value * (1 - N) + end-value * N) - if both start and end values come from different trees, they're now being mashed into a single value, living in some single tree somewhere (probably not either of the source trees!).

anchor() is the first tree-scoped reference where this really matters - all the other instances are discretely animated (like 'font-family'), so once you resolve the start and end values to something concrete, they just flip between the two and it's reasonably fine.† But anchors can move during the transition, and you want to track them!

I think this should be fixable with some magic, stating that when you construct the transition style it resolves its tree-scoped references first, and this partially-resolved value is what's being transitioned.

/cc @xiaochengh @bfgeek @dbaron @emilio @smfr ?


† In theory, if we fully ate our own dogfood and represented these with some sort of transition(discrete 20%, start-value, end-value) function it would be just as problematic, but we do magic instead so it's fine. I suppose we probably ignore if you change one of the @font-face rules partway thru the transition, maybe? Not a use-case we really worry about.

@tabatkins
Copy link
Member Author

Yeah I think that's the way to go - tree-scoped references must be resolved at computed-value time, to whatever it is they represent. Then the transition style just uses those resolved-ref values and everything is well-defined; the location of the transition style sheet doesn't matter.

This still works correctly with inheritance, too, we're just carrying a slightly different non-textual value around. Rather than a pair of (reference value, tree pointer), we carry around "whatever that reference would resolve to": a set of font faces, an anchor element, etc.

@xiaochengh
Copy link
Contributor

tree-scoped references must be resolved at computed-value time, to whatever it is they represent.

This seems to allow invalid anchor references by inheritance. For example:

<div id="anchor" style="anchor-name: --a"></div>
<div id="div1" style="position: absolute; left: anchor(--a left)">
  <div id="div2" style="position: absolute; left: inherit"></div>
</div>

If we resolve anchor() at computed value time, then #div2 gets #anchor as its anchor via inheritance. But this is invalid because #anchor is not in the same containing block of #div2.

@xiaochengh
Copy link
Contributor

Btw, this "resolve reference at computed value time" approach doesn't seem to work for animations, because there's no anchor references at all in computed values; they all come from keyframes, i.e., animation origin style

@xiaochengh
Copy link
Contributor

I have an alternative idea which is less groundbreaking and should fix this issue, but not the other (#8181).

Currently, tree-scoped reference is defined at a per-property level, namely, only a property's whole value is tree-scoped:

Properties or descriptors that reference a "global" name, such as the font-family or animation-name properties, must define their value as a tree-scoped reference.

We just need to change it to per CSS value.

Then if two CSS values are combined into a calc expression, their tree-scoped references must remain as-is in the combined expression tree. This allows preserving the tree scope references in the result of an addition and interpolation. It also allows combing two values from different tree scopes.

Then it should already work for transition styles, because it only applies an interpolation between two computed styles to the element, and the two computed styles should already have tree-scoped references.

Same for CSS animations: CSS keyframes can be tree-scoped by the hosting stylesheets, and then the animation style is just a combination of the keyframes.

I'm not sure how to make it work with Web Animation API though, because JS is not naturally tree-scoped. But I think this is a more general issue that's not limited to anchor positioning (see eg test case for counter styles).

@tabatkins
Copy link
Member Author

We just need to change it to per CSS value.

Ah, that is in fact already what I intended with that Scoping spec text, but I see that I don't actually say that. I should fix it!

jakearchibald pushed a commit to jakearchibald/csswg-drafts that referenced this issue Jan 16, 2023
@xiaochengh
Copy link
Contributor

I think this is already resolved and can be closed?

@tabatkins
Copy link
Member Author

Even more importantly, resolved by #9598's "interleaving". Closing.

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

No branches or pull requests

2 participants