csswg-drafts icon indicating copy to clipboard operation
csswg-drafts copied to clipboard

[css-anchor-position-1] Behavior with transforms and offset-path

Open kizu opened this issue 2 years ago • 9 comments

Disclaimer and additional links

I'm submitting my feedback following my experiments with the current implementation of anchor positioning in Chrome Canary.

I wrote an article about my experiments, but decided to fill most of my feedback as separate issues here.

A quick summary of related links:

Right now, the positions for the anchors do not take into account things like transforms, offset-path (position: sticky, which is covered by https://github.com/w3c/csswg-drafts/issues/8448).

In practice, there were cases in my experiments where I wanted to use those — transforms and offset-path for the animations/transitions (see the animations for the “four quadrants” in my article — I want to attach things that move, but because transforms or offset-paths are not used, I have to animate things via top and left).

Currently, specs do not mention any of these cases — if those are intended to not be supported, the specs should be clarified, but I would suggest looking into providing an option to somehow follow those.

I understand that for the transforms and offset-path things are probably much more complicated — but I foresee a lot of cases where developers would want an option to follow those. I wonder if this could be something like anchor-transform or whatever, which could be optionally used with transform on the anchored element? And maybe something similar with offset-path (though, maybe it could be similar to position: sticky in that it is easier to describe how it could work by default?)

kizu avatar Mar 15 '23 12:03 kizu

It should definitely work with position: sticky, but we haven't done the spec work yet: #8448

Would you mind splitting this bug by moving the stickypos related stuff to #8448 and leaving the remaining here?

xiaochengh avatar Jun 01 '23 20:06 xiaochengh

Not taking transforms into account (including offset transforms) is intentional - nothing else does, either, because they're strongly post-layout, purely visual effects (and disrupt the notion of elements having a "left side"/etc, outside of their local transform context).

tabatkins avatar Jun 02 '23 17:06 tabatkins

(copied with modifications from the OpenUI discord)

I thought about a case where we'd want to follow the transform of the target's container: https://codepen.io/kizu/pen/WNLYRvx

Basically, what if we want to attach a popover to a button inside a rotated, or otherwise transformed container?

Here is what we get right now in this example (in Canary with experimental platform features flag due to anchor positioning), when the element is outside of the rotated container (inside the rotated one things are obviously ok), or when it is yoinked into the topmost layer via popover API:

A screenshot of an example with a button and a popover, where the button is placed in a rotated container, with a popover attached to it, but the popover itself is not rotated, so it is “detached” from the button

This can also be a case for when someone implements a sliding side-panel, with sliding animated via a transform, but then what if the panel would contain a defaultOpen popover that should be attached to some element via anchor positioning? With the way things work now, that element would exist completely outside of the transformed space, and to replicate what we want to achieve, we'd have to do a lot of work by manually transforming the popover.

For regular abspos, we could argue, that the idea was that we now could place the popover near the element, so we would expect the behavior as in the third container in the codepen:

A screenshot of a rotated container, a button inside and an abspos element attached to the button, following the rotation of the container.

But then, when we have a Popover API — the element is reparented to the topmost layer, thus loses that transformation context.

Should we be able to either somehow follow a transformation of a selected element, or be able to disable putting the element in the topmost layer (which, I imagine, can be problematic on its own?), or something else?

kizu avatar Oct 05 '23 21:10 kizu

It seems doable to me if we want to additionally apply additional transforms to the anchored element after layout. There are some issues with the transform origin, but they may be fixable.

The issue is that it won't work well with position fallback, because it's post-layout. And I don't see any way to make position fallback work with general transforms.

xiaochengh avatar Oct 05 '23 21:10 xiaochengh

I think it might be reasonable to lose the ability to apply fallbacks when following the transforms. Though, I wonder if this is something that might benefit from a property/keyword somewhere that controls this? Could there be cases where there'd be a transform which we don't want to follow? Something like “neutral” transforms, like the initial state ones (scale(1), translateZ(0) etc) come to mind, where an element could have it, but the developers would not want this to interrupt the fallback mechanism.

kizu avatar Oct 05 '23 21:10 kizu

Could there be cases where there'd be a transform which we don't want to follow?

I think this might be the common case. If the style doesn't explicitly have a transform, then there shouldn't be any transform.

Exceptions might only be cases similar to <selectlist>, which look broken if the popover doesn't follow the transform by default.

xiaochengh avatar Oct 05 '23 22:10 xiaochengh

Right - we don't want to allow a layout dependency on transforms unfortunately. Lots of things are accelerated for users, and this would force a bunch of things onto a slow path.

bfgeek avatar Oct 06 '23 20:10 bfgeek

There doesn't seem to be any discussion of offset-path here, do I need to open a separate issue?

Test in Chrome 127: https://codepen.io/yisi/pen/eYaJopE

https://github.com/w3c/csswg-drafts/assets/2784308/840b1cdb-f3b2-4240-b2e0-9a08d82a633c


Chrome bugs: https://issues.chromium.org/issues/341875179

yisibl avatar May 20 '24 03:05 yisibl

Many web apps with a "canvas" UI use transforms as a key part of their rendering. I.e. translate() to handle panning and scale() to handle zooming. Anything built using react-flow for example. Adding tooltips, popovers and context menus on canvas items is an common requirement for these apps, but if I read this correctly, it will be impossible to use anchor positioning for these kinds of use-cases? If so, that seems like a big gap.

jonrimmer avatar Jul 04 '24 12:07 jonrimmer

It's perhaps also worth nothing that the most popular JS library for achieving anchored positioning, Floating UI (the successor to Popper.js), does take CSS transforms into account, so as it stands anchor-positioning will not be adequate to replace it.

jonrimmer avatar Jul 08 '24 15:07 jonrimmer

It is possible to apply offsets and scales in these cases, you just need it to explicitly do it on the anchored element as well.

The issue with accounting for transforms is that it'd force the transform animations on such elements (and any of their ancestors) to not be off-main-thread, and affect layout, which is a no-no.

emilio avatar Oct 31 '24 21:10 emilio

@jonrimmer indeed I am here because my app is using canvas features like translate and scale, and having anchored elements that could scale with both would be great

currently we are doing all of this inside a animation frame loop

Although, I understand that elements will properly scale and translate if they are contained within the element containing the CSS transforms.

I can imagine various potential workarounds to get the anchor element existing outside of that transformed context to still respond to the transformed child

AlbertMarashi avatar Oct 31 '24 23:10 AlbertMarashi

So, what should the spec say?

Current status:

https://drafts.csswg.org/css-anchor-position-1/#determining-position

Post-layout effects, such as transform, do not affect the anchor box’s position. Note: Allowing an anchor to opt into including the effects of transform or similar properties might be allowed in the future.

Then, about taking scrolling into account: https://drafts.csswg.org/css-anchor-position-1/#issue-141fd32f

Transforms have the same issue as scrolling, so Anchor Positioning similarly doesn’t pay attention to them normally. Can we go ahead and incorporate the effects of transforms here?

And: https://drafts.csswg.org/css-anchor-position-1/#issue-a8569080

Similar to remembered scroll offset, can we pay attention to transforms on the default anchor element?

Do we want to take an anchor's transforms into account, and how far would we like to go? Only honor those on the default anchor when at an anchor recalculation point? Or more? We don't want to allow transforms to affect layout, ever, I assume, not even as an opt-in? Because that means main-thread work, and no compositing.

Otherwise we could do funny things like this (video below):

<!DOCTYPE html>
<style>
  .transform {
    transition: 2s transform;
  }
  .transform:hover {
    transform: rotate(500deg) scale(0.5) translateX(200px);
  }
  .dot {
    position: absolute;
    position-anchor: --a;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: hotpink;
  }
</style>
<div style="width:fit-content; margin:100px;">
  <div class="transform" style="display:inline-block; anchor-name:--a; width:350px; height:350px; background:cyan;">
    Hover me. Whee!
  </div>
</div>
<div class="dot" style="position-area:right;"></div>
<div class="dot" style="position-area:left;"></div>
<div class="dot" style="position-area:top;"></div>
<div class="dot" style="position-area:bottom;"></div>

https://github.com/user-attachments/assets/a8ce8ef9-3f53-4e17-b49a-871a9876fc4d

And by taking an anchor's transforms into account, use its bounding box after transforms have been applied?

mstensho avatar Apr 24 '25 09:04 mstensho

Do we want to take an anchor's transforms into account, and how far would we like to go? Only honor those on the default anchor when at an anchor recalculation point? Or more? We don't want to allow transforms to affect layout, ever, I assume, not even as an opt-in? Because that means main-thread work, and no compositing.

Right, the potential for layout effects is the obvious problem here.

So just to review how we handle scroll:

  • at anchor recalculation points, we calculate all anchor references based on their actual scrolled position. (So anchor() resolves to the scroll-accurate offset, and you can get accurate results from max(anchor(top), anchor(--foo top))/etc.) This is capable of changing the the size of the positioned element.
  • at all times, we track the default anchor's scroll offset, and when it differs from the remembered scroll offset from the last anchor recalculation point, we apply the difference as a translate to the positioned element. (So anchor()/etc do not respond to this difference, and the max() example might no longer be correct, etc.) Since it's a transform, this is not capable of changing the size of the positioned element; it just shifts it.

The live-responding transform is a little clumsy, since it can break constraints you write into your offsets. It's a reasonable compromise, tho, for the benefit of being able to "stick to" the default anchor reliably.

If we want transforms to work similarly, we need to adopt similar constraints.

  • at anchor recalculation points, we calculate all anchors based on their actual transformed position (using the axis-aligned 2d bounding box of the transformed anchor).
  • at all times, we track the default anchor's transform. We need to track some point on the default anchor (I'll discuss which point later) - when its position differs from its position at the last anchor recalculation point, we apply the difference as a translate.

Which point, tho? Translates don't really care which we use, but rotates and scales definitely do. And is the point on the anchor itself, or on its transform bounding box? I think the right answer is that it's a point on the bounding box. But which point? I think the "right" answer is going to depend on some other properties.

  • We should have a property (anchor-transform?) that lets you specify this point explicitly, so you can do whatever you want.
  • Otherwise (if the property is auto), if the positioned element is using position-area, we can infer a reasonable point based on the area:
    • If the area has exactly one corner touching one of the anchor's corners, use that corner. (Numbering the area sections like a phone keypad, areas like "1" or "1245".)
    • Otherwise, if the area has exactly one edge touching one of the anchor's sides in an axis, use the center of that side. (Areas like "2", "12", "123", "25", or "123456".) (It can either touch both sides in the other axis, like "25", or neither in the other axis, like "123".)
    • Otherwise, use the center of the bounding box. (Areas like "5" or "123456789".)
    • (Afaict, this will actually let you reproduce the "dots on the edge of a spinning box" video you posted.)
  • Otherwise, use the center of the bounding box. (This will make it respond to translations, but not the anchor rotating or scaling itself at all. That's intentional, since we can't guess at what part we're intending to anchor to.)

The unstated next question is whether it's possible to do this by default at this point, or if we need to continue ignoring transforms by default and key it to the property that controls what point we're tracking (like anchor-transform: none as the initial value, and anchor-transform: auto/etc would turn it on).

tabatkins avatar May 13 '25 20:05 tabatkins

Do we want to take an anchor's transforms into account, and how far would we like to go? Only honor those on the default anchor when at an anchor recalculation point? Or more? We don't want to allow transforms to affect layout, ever, I assume, not even as an opt-in? Because that means main-thread work, and no compositing.

Right, the potential for layout effects is the obvious problem here.

So just to review how we handle scroll:

  • at anchor recalculation points, we calculate all anchor references based on their actual scrolled position. (So anchor() resolves to the scroll-accurate offset, and you can get accurate results from max(anchor(top), anchor(--foo top))/etc.) This is capable of changing the the size of the positioned element.
  • at all times, we track the default anchor's scroll offset, and when it differs from the remembered scroll offset from the last anchor recalculation point, we apply the difference as a translate to the positioned element. (So anchor()/etc do not respond to this difference, and the max() example might no longer be correct, etc.) Since it's a transform, this is not capable of changing the size of the positioned element; it just shifts it.

The live-responding transform is a little clumsy, since it can break constraints you write into your offsets. It's a reasonable compromise, tho, for the benefit of being able to "stick to" the default anchor reliably.

If we want transforms to work similarly, we need to adopt similar constraints.

  • at anchor recalculation points, we calculate all anchors based on their actual transformed position (using the axis-aligned 2d bounding box of the transformed anchor).

This one sounds like the bare minimum (and maybe enough?), pretty straight-forward to solve, and will be similar to how we already deal with scrolling, yes. No opt-in mechanism needed for this, as far as I can tell (we didn't add one when implementing this for scrolling although it was a behavior change).

  • at all times, we track the default anchor's transform. We need to track some point on the default anchor (I'll discuss which point later) - when its position differs from its position at the last anchor recalculation point, we apply the difference as a translate.

So this is for a more broad support for transforms (not just at recalculation points), briefly mentioned in https://drafts.csswg.org/css-anchor-position-1/#determining-position

We don't have to solve or spec both these at the same time. Responding at anchor recalculation points will most likely cover most use cases. At the same time, it would be interesting to know how far we would like to go.

Which point, tho? Translates don't really care which we use, but rotates and scales definitely do. And is the point on the anchor itself, or on its transform bounding box? I think the right answer is that it's a point on the bounding box. But which point? I think the "right" answer is going to depend on some other properties.

  • We should have a property (anchor-transform?) that lets you specify this point explicitly, so you can do whatever you want.

  • Otherwise (if the property is auto), if the positioned element is using position-area, we can infer a reasonable point based on the area:

    • If the area has exactly one corner touching one of the anchor's corners, use that corner. (Numbering the area sections like a phone keypad, areas like "1" or "1245".)
    • Otherwise, if the area has exactly one edge touching one of the anchor's sides in an axis, use the center of that side. (Areas like "2", "12", "123", "25", or "123456".) (It can either touch both sides in the other axis, like "25", or neither in the other axis, like "123".)
    • Otherwise, use the center of the bounding box. (Areas like "5" or "123456789".)
    • (Afaict, this will actually let you reproduce the "dots on the edge of a spinning box" video you posted.)

The big question here is if that's a use case we want to support at all. I just made it as an extreme example. Oh wait, I had left one thing out for "simplicity". Here's another one, with rectangles that get sized by a position-area that's affected by transforms.

Same as the previous example, plus this:

<style>
  .box {
    position: absolute;
    position-anchor: --a;
    width: 100%;
    height: 100%;
    background: lightgray;
  }
</style>
<div class="box" style="position-area:top right;"></div>
<div class="box" style="position-area:top left;"></div>
<div class="box" style="position-area:bottom left;"></div>
<div class="box" style="position-area:bottom right;"></div>

https://github.com/user-attachments/assets/dcb85b5a-d37d-40da-a80f-7e9c2bda72a7

As long as we respond to transforms only at anchor recalculation points, that seems fine. My examples rely on more responsiveness than that. Although the last example is the only one that has boxes that get resized based on transform changes, it's not that different from the first example. The first example only changes the offsets of the anchored elements, but in our implementation at least, this means performing layout (nothing is resized, but their offsets in the layout fragment tree change - that's main thread stuff). Does this throw a spanner in your thought works?

  • Otherwise, use the center of the bounding box. (This will make it respond to translations, but not the anchor rotating or scaling itself at all. That's intentional, since we can't guess at what part we're intending to anchor to.)

The unstated next question is whether it's possible to do this by default at this point, or if we need to continue ignoring transforms by default and key it to the property that controls what point we're tracking (like anchor-transform: none as the initial value, and anchor-transform: auto/etc would turn it on).

If we only respond at anchor recalculation points, I think we can do it by default. Then it's just like scrolling.

mstensho avatar May 14 '25 08:05 mstensho

This one sounds like the bare minimum (and maybe enough?), pretty straight-forward to solve, and will be similar to how we already deal with scrolling, yes. No opt-in mechanism needed for this, as far as I can tell (we didn't add one when implementing this for scrolling although it was a behavior change).

Yeah, my only concern is compat, tho that's probably safe to do at this point, as long as we don't dawdle too much.

We don't have to solve or spec both these at the same time. Responding at anchor recalculation points will most likely cover most use cases. At the same time, it would be interesting to know how far we would like to go.

Right, we can indeed separate them, especially if we tie the "live" transform tracking to an opt-in property.

Although the last example is the only one that has boxes that get resized based on transform changes, it's not that different from the first example.

Resizing makes it pretty significantly different. ^_^

The first example only changes the offsets of the anchored elements, but in our implementation at least, this means performing layout (nothing is resized, but their offsets in the layout fragment tree change - that's main thread stuff). Does this throw a spanner in your thought works?

No, I think that's just an artifact of how you're currently doing things under the covers. My proposed behavior is that the "live" offset be applied as a translation, not a layout offset. That should hopefully allow us to avoid main-thread work.

tabatkins avatar May 15 '25 17:05 tabatkins

I suggest that we focus on dealing with anchor recalculation points first, and then figure out any opt-in mechanism for "live" transforms later.

It seems pretty obvious to me how this (at recalculation points) is supposed to work, so, although the spec needs to be updated, I can go ahead and land something.

mstensho avatar May 20 '25 07:05 mstensho

Right. So just to confirm, so I can edit accordingly: in the section where we talk about handling scroll at recaluculation points, we also say that we pay attention to transforms, and use the transform bounding box of the anchor (in the coordinate space of the positioned element's containing block) instead of the anchor's actual box.

I note this does interact a bit with the request to use different boxes from the anchor (right now we always use the anchor's border box edge). Not sure how we'd handle using padding/content box, unless maybe by applying the same transforms to that reduced box and then finding the bounding box of that.

Anyway, something to solve for later; paying attention to transforms on the anchor is definitely more important than caring about the content box of an anchor.

tabatkins avatar May 22 '25 00:05 tabatkins

Firstly, I'd just like to point out that there'd already be a similar issue regarding border-box vs. padding-box / content-box for fragmented content. https://www.w3.org/TR/css-anchor-position-1/#anchor-pos The spec currently says:

If the target anchor element is fragmented, the axis-aligned bounding rectangle of the fragments' border boxes is used instead.

Apart from that: yes, that's exactly what I'm thinking: Use the bounding box with transforms applied.

However: I realized that there's one concern here, about "anchor recalculation points". What if the anchor is resized or moved (and also why not change the transform at the same time?)?

<!DOCTYPE html>
<style>
  #anchor {
    transform-origin: top left;
    scale: 2;
    anchor-name: --a;
    width: 50px;
    height: 50px;
    background: cyan;
  }
  #anchored {
    position: absolute;
    position-anchor: --a;
    width: 100%;
    height: 100%;
    border: dotted;
    box-sizing: border-box;
  }
</style>
<div style="position:relative;">
  <div id="anchor"></div>
  <div id="anchored" style="position-area:right;"></div>
</div>

Now do this:

    anchor.style.width = "100px";
    anchor.style.scale = "1";

When an anchor is resized or moved, that should obviously affect any anchored elements, so any such bounding box that we calculated at the previous anchor recalculation point needs to be updated somehow. But transforms may have changed in the meantime as well. What to do?

mstensho avatar May 26 '25 08:05 mstensho

When an anchor is resized or moved, that should obviously affect any anchored elements, so any such bounding box that we calculated at the previous anchor recalculation point needs to be updated somehow. But transforms may have changed in the meantime as well. What to do?

Ah, took me a sec to realize what the question was here. We track layout changes "live", but only track scroll offset changes at the specific recalculation points, and the question is whether transform changes should act like layout or like scroll.

I agree it would be weird if both the layout and transform changes, but we don't update the transform adjustment, because the anchor would be off in a weird way.

But what if only the transform updates? That is meant to be hardware-accelerateable, like scrolling, so tracking it live would cause the same issues as tracking scrolling - it might be a frame or two late, which looks really bad when the positioned element is trying to "stick" to the anchor.

I'm not sure what the right answer is here. :/

tabatkins avatar Jul 22 '25 16:07 tabatkins

I'm not sure what the right answer is here. :/

I think we should treat transform the same as layout-affecting properties--if it changes, then schedule a re-render. This will get behind by a frame or so during a threaded animation of transform, but that's better than breaking when transform+layout changes at the same time.

chrishtr avatar Jul 22 '25 22:07 chrishtr

The CSS Working Group just discussed [css-anchor-position-1] Behavior with transforms and offset-path, and agreed to the following:

  • RESOLVED: Anchor positioning will take transforms into account.
The full IRC log of that discussion <fantasai> kizu: problem we have with anchor positioning is that it currently doesn't behave well when the anchor is transformed or offset-path
<fantasai> kizu: have an element, it's positioned over offset path, the anchor element will not be in the correct position
<fantasai> kizu: there are many cases where you might want something like this
<TabAtkins> Q+
<fantasai> kizu: e.g. popover and you have ??? and you rotate something someway, you will expect your popover to be closer to the target
<fantasai> kizu: right now it might get completely off the target
<fantasai> kizu: long discussion, some last comments say, maybe it's possible to do this
<fantasai> kizu: but not in a way that the anchored element will be a bit behind by a frame or two
<fantasai> kizu: my personal opinion, this is okay
<fantasai> kizu: it is better than not being at the right position at all
<chrishtr> +1 to it being ok
<fantasai> kizu: when we first implemented position: sticky and fixed, and over time we improved the behavior
<fantasai> kizu: this might be a similar case
<fantasai> kizu: we might not be able to make it look and behave perfectly as you expect, but maybe in the future it will work
<fantasai> kizu: but authors expect anchored elements to be close to their anchor
<fantasai> kizu: otherwise it looks like a bug, and authors will not be able to replace their current solutions with anchor positioning
<astearns> ack TabAtkins
<fantasai> TabAtkins: Transforms, implementation-wise, fall into a similar bucket as scrolling, where they are hardware-accelerated
<fantasai> TabAtkins: limitations we have with anchor positioning are to avoid having lag
<fantasai> TabAtkins: but since initial version of anchorpos, we've done significant work to make those limitations as invisible as we can
<fantasai> TabAtkins: most of the time you don't need to worry about scrolling, it does the reasonable thing
<fantasai> TabAtkins: intention was always to address transforms
<chrishtr> Animating scrolling is much more common than transform. Transform is also sometimes used by developers as a "layout feature", e.g. offset by 50% relative to viewport
<fantasai> TabAtkins: we should address that now, so we don't get compat dependence on current behavior
<fantasai> TabAtkins: I agree that transfroms are sufficiently layout-like that it's worth making sure it's always correct
<fantasai> TabAtkins: so I think we should live update in response to transforms same as we do with layout today
<emilio> q+
<fantasai> TabAtkins: accept that it won't be perfect
<fantasai> TabAtkins: so we should do this work
<astearns> ack fantasai
<TabAtkins> fantasai: one thought that might be worth exploring is making it work for transforms other than the transform property itself
<TabAtkins> fantasai: so translate, offset-path, etc, but not transform itself
<TabAtkins> fantasai: maybe separating out the transform property itself would help
<astearns> ack emilio
<TabAtkins> fantasai: might avoid us having to worrya bout 3d, let the author decide what to respond to
<TabAtkins> fantasai: may not be a good idea, just throwing it out
<TabAtkins> emilio: so proposal is to make transformed anchors not block a sync animation
<TabAtkins> emilio: which would be the alternative
<TabAtkins> emilio: forcing those animations onto the main thread
<fantasai> TabAtkins: Yeah, no demotion of animations
<fantasai> TabAtkins: that would require arbitrary walking up to other elements in the tree that might be transformed and affecting this
<fantasai> emilio: Yeah that was my concern
<chrishtr> Or you could say that it's up to UAs to decide whether they prefer main thread transform animations or sometimes lagging anchors
<fantasai> emilio: Real question is, if this is good enough ... but probably it's better to do this?
<flackr> my general thinking is that authors can roughly think of it as anchoring to the bounding box in the space of the anchor's offset parent
<fantasai> emilio: Makes changes to 'transform' affect layout in deeper ways, though right now it only affect scrollable overflow which does affect content (which is annoying)
<fantasai> emilio: optimizing that is scary
<fantasai> TabAtkins: Proposal is that anchor positioning takes transforms of its anchors into account, same as it takes changes to layout into account
<fantasai> astearns: Decide if we want to reduce scope of this to e.g. avoid 3D transforms
<fantasai> astearns: Objections?
<fantasai> emilio: Not objecting, but it's not great to do style invalidation for changes in transforms
<fantasai> flackr: It could be visually incorrect for a few frames, but once you do style update on main thread, it'll update
<fantasai> emilio: Animations I'm ok with it
<fantasai> emilio: but let's say you update transforms via script. Right now it's very cheap
<fantasai> emilio: only affects a few things, doesn't require style recalc
<chrishtr> I think it's ok to have this dependency when anchors are present
<fantasai> emilio: But with this change, you would need to make that change
<fantasai> emilio: feels unfortunate
<TabAtkins> yes, dirtying based on transforms is implied here
<chrishtr> +1 to tests, Morten will add them
<fantasai> emilio: You would need lots of tests for this... transforms are well-optimized in engines right now, and this will break some of those
<TabAtkins> fantasai: one possibility is only do this for position-area changes, not for anchor computations. that would avoid style recalc
<fantasai> TabAtkins: It's not the problem, it's dirtying layout which is the problem
<chrishtr> +1 to resolve now and continue discussing other details
<fantasai> astearns: So are we going to resolve on this, or dig into implications?
<fantasai> emilio: Fine resolving now, if considered all these
<fantasai> RESOLVED: Anchor positioning will take transforms into account.

css-meeting-bot avatar Jul 23 '25 17:07 css-meeting-bot

One question that came up in the call was whether this should affect all transforms, or only non-transform transforms (which are more limited).

fantasai avatar Jul 23 '25 17:07 fantasai

They're not meaningfully limited. translate/rotate/scale can do 2d or 3d transforms, and offset-path can do a combination of 2d translate and rotate. The only real extra power that transform gives is the skew functions, and arbitrary matrix, but those are not meaningfully different for these purposes.

(If it was a "2d vs 3d" distinction there might have been an argument, I think, but since that ship's already sailed, I don't see any reason to distinguish the various transform sources.)

tabatkins avatar Jul 23 '25 17:07 tabatkins

Does this mean that my example in https://github.com/w3c/csswg-drafts/issues/8584#issuecomment-2879321841 should work, including resizing of the gray rectangles in the corners?

mstensho avatar Jul 23 '25 19:07 mstensho

Does this mean that my example in #8584 (comment) should work, including resizing of the gray rectangles in the corners?

Yes, I think so. Except that the anchored element might fall behind during the transition animation by a frame or so.

chrishtr avatar Jul 23 '25 19:07 chrishtr

Right. Except for the possibility of frame slippage, it should work exactly the same as just animating the width/height/position of a box (matching the size/position of the bounding box) and anchoring to that instead.

tabatkins avatar Jul 23 '25 19:07 tabatkins

Many virtual scroll solutions use transform to scroll recycled elements. Without a way to allow anchor-position to follow those transforms creating native tooltips using popover="hint" wouldn't be possible.

So although slower if default it should be possible to opt-in to following transform.

john-melin avatar Aug 06 '25 07:08 john-melin

All right, transform text is in the spec now, in https://drafts.csswg.org/css-anchor-position/#anchor-position-size.

As far as @fantasai and I could tell, this only really needed a few sentences to define. Are there any details we missed?

tabatkins avatar Sep 26 '25 22:09 tabatkins