[csswg-drafts] [css-position] Sticky positioning when constraining flow box is not in containing block chain

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

== [css-position] Sticky positioning when constraining flow box is not in containing block chain ==
<details>
<summary>Consider this code: <a href="http://jsfiddle.net/4r6ubdvo/">http://jsfiddle.net/4r6ubdvo/</a></summary>

```html
<div id="scroll">
  Scroll
  <div id="fixed">
    Fixed
    <div id="sticky">Sticky</div>
  </div>
</div>
```
```css
#scroll {
  overflow-y: scroll;
  height: 100px;
  border: 3px solid;
  margin-top: 50px;
}
#scroll::after {
  content: '';
  display: block;
  height: 400px;
}
#fixed {
  position: fixed;
  background: #ff0;
  height: 100px;
  top: 0;
  left: 100px;
  border: 3px solid;
}
#sticky {
  position: sticky;
  top: 0;
  background: #0ff;
  border: 3px solid;
}
```
</details><br />

The "flow box which are used to constrain" the stickily positioned element `#sticky` is `#scroll`. However, between them there is a fixed positioned element , `#fixed`. Therefore, `#scroll` is not in the containing block chain of `#sticky` and scrolling `#scroll` does not affect the position of `#fixed`.

How should `#sticky` react to this?

According to https://drafts.csswg.org/css-position/#sticky-pos,

> A rectangle is computed relative to the containing block of the stickily positioned element, by insetting its flow box rectangle on each side by offsets computed from the left, right, top and bottom properties of the stickily positioned element. 
> The intersection is taken between the resulting rectangle, and the containing block of the stickily positioned element. The result, termed the the sticky-constraint rectangle, is a rectangle used to constrain the location of the stickily positioned element. 

So the sticky element should be shifted downwards in order to appear inside `#scroll`. This is what Chromium does, however, scrolling `#scroll` moves `#sticky`. I guess it tries to counteract the scrolling without realizing it had no effect due to the fixed ancestor.

In Firefox, `#scroll` does not constrain `#sticky` because it's not in the containing block chain. If you add `transform: scale(1)` so that it generates a containing block for fixed descendants, then it constrains. http://jsfiddle.net/4r6ubdvo/1/

I think Firefox's behavior makes more, sense, i.e. redefine https://drafts.csswg.org/css-position/#sticky-position to

> A stickily positioned box is positioned similarly to a relatively positioned box, but the offset is computed with reference to the nearest ancestor **in the containing block chain** with a scrolling box, or the viewport if no ancestor has a scrolling box.

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

Received on Monday, 1 October 2018 10:26:55 UTC