[csswg-drafts] [css-anchor-position-1] Define precisely when anchor recalc points happen, and which offsets it captures. (#12371)

emilio has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-anchor-position-1] Define precisely when anchor recalc points happen, and which offsets it captures. ==
https://drafts.csswg.org/css-anchor-position-1/#anchor-recalculation-point says:

> An anchor recalculation point occurs for an [absolutely positioned element](https://drafts.csswg.org/css-position-3/#absolute-position) whenever that element begins generating boxes (aka switches from display:none or display:contents to any other [display](https://drafts.csswg.org/css-display-4/#propdef-display) value), identical to when it starts running CSS animations.

That's fair enough.

> An [anchor recalculation point](https://drafts.csswg.org/css-anchor-position-1/#anchor-recalculation-point) also occurs for an element when [determining position fallback styles](https://drafts.csswg.org/css-anchor-position-1/#determine-position-fallback-styles) for that element; if it changes fallback styles as a result, it uses the result of the anchor recalculation point associated with the chosen set of fallback styles.

That's also ok (so, when the box overflows its inset-modified containing-block).

But it seems to me it's missing a bunch of cases. My understanding is that it should at least also recalc them when the anchor references change. E.g., consider ([live](https://crisal.io/tmp/anchor-pos-scroll-1.html)):

<details>

```html
<!DOCTYPE html>
<style>
  #anchor {
    anchor-name: --input;
    margin-top: 200px;
  }
  #anchored {
    display: none;
    color: white;
    position: absolute;
    margin: 10px;
    top: anchor(bottom);
    border-radius: 5px;
    background: teal;
    padding: 5px;
  }
  #scroller {
    width: 300px;
    height: 300px;
    overflow: auto;
    position: relative;
    resize: both;
  }
  #filler {
    height: 2000px;
  }
</style>
<div id="scroller">
  Focus me:
  <input id="anchor" type="text">
  <div id="filler"></div>
</div>
<div id="anchored"></div>
<script>
  scroller.scrollTop = 50;
  setTimeout(() => {
    anchored.style.display = "block";
  }, 1000);
  anchor.addEventListener("focus", () => {
    anchored.style.positionAnchor = "--input";
  });
</script>
```

</details>

I think per spec, when focusing, the anchored element should be anchored without accounting for the scroll position.

Also, if you change `anchored.style.positionAnchor = "--input";` by `anchored.style.bottom = "anchor(--input bottom);`, ([live](https://crisal.io/tmp/anchor-pos-scroll-2.html)) I would expect the behavior to be identical, but it isn't, and now the scroll offset isn't applied.

My understanding is that both should create an [anchor reference](https://drafts.csswg.org/css-anchor-position-1/#anchor-reference). Per my read of the spec, both should be "unanchored" on scroll. If you amend the spec to do anchor recalcs on all style changes that introduce new anchor references, then both should be anchored on scroll, right? It's not clear to me what is going on / what in the spec would justify that difference?

cc @lilles @tabatkins @anttijk

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12371 using your GitHub account


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

Received on Thursday, 19 June 2025 14:42:56 UTC