-
Notifications
You must be signed in to change notification settings - Fork 756
Description
Consider this code: http://jsfiddle.net/4r6ubdvo/
<div id="scroll">
Scroll
<div id="fixed">
Fixed
<div id="sticky">Sticky</div>
</div>
</div>#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;
}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.