Bug 175029

Summary: "position:sticky" does not work correctly in flex item
Product: WebKit Reporter: Ivan Poluyanov <i.poluyanov>
Component: CSSAssignee: Martin Robinson <mrobinson>
Status: RESOLVED WORKSFORME    
Severity: Major CC: cigitia, hi, jonathan.cammisuli, mrobinson, simon.fraser, webkit
Priority: P2    
Version: Safari 10   
Hardware: Mac   
OS: macOS 10.12   

Description Ivan Poluyanov 2017-08-01 09:21:09 PDT
Element with "position: sticky" stucks in the bottom of the flex element with "overflow-y: auto" as if "overflow-y: auto" was not set.

Examples:

with "overflow-y: auto":
https://jsfiddle.net/4hwgfz4z/

without:
https://jsfiddle.net/ed95kw7x/

If i get rid of flex - everything is ok: 
https://jsfiddle.net/6bu8kua5/

Firefox and Chrome handle this case(https://jsfiddle.net/4hwgfz4z/) correctly, element stops in the bottom of scrollable element.
Comment 1 webkit 2017-08-04 11:09:03 PDT
I'm just running up against this as well, and it's pretty tough.

Here is an additional example that illustrates the issue as well: https://jsbin.com/femamusete/2/edit?html,css,output

If there are any known workarounds, I'd appreciate the knowledge share!
Comment 2 Jonathan Cammisuli 2018-02-12 14:30:01 PST
I'd like to add some more information for this bug. 


In my case, I have a layout that has has two panels. Left and Right, like so:
https://codepen.io/anon/pen/LQLjKO

Green area, should stick to the top with 0, gray row should stick to the top by 3.5rem.

When scrolling, the green area stays for what appears to be the height of the container, then scrolls away. The interesting thing here, is that the gray area stays in it's designation sticky spot, no matter what. Also note, that I have left: 0 on the pink area, and the green area, so that horizontal scrolls stick those elements.

By trying the above example on either Chrome or Firefox, we can see that it's working there, with no issues.
Comment 3 jonjohnjohnson 2018-04-23 15:12:12 PDT
i.poluyanov@icloud.com
webkit@jmailer.xyz
jonathan.cammisuli@soti.net

As far as work arounds, all of your examples could be "fixed" by putting another element inside the scrolling element that wraps around all the contents. This effectively acts as a containing block for any sticky elements inside the "scrollport". Give it a min-height to match the scroller if you want. Otherwise use display flex on each.

This is due to sticky positioning as a feature, being quite underspecified. And though firefox/chrome, allow a scrolling elements "scrollHeight" to be used for wrapping sticky elements, safari (I think) uses the scrolling elements "clientHeight" to analyze the "sticky constraint rectangle".

Demo #2 -> http://usefulangle.com/post/40/javascript-client-height-vs-offset-height-vs-scroll-height

The spec is unclear if Safari should match other implementations, but for interop, I hope they do.

Just to reiterate, this isn't do to display flex.
Comment 4 jonjohnjohnson 2018-04-23 15:13:37 PDT
*due to display flex :P
Comment 5 Martin Robinson 2021-08-20 06:05:21 PDT
I have tested https://jsfiddle.net/4hwgfz4z/ with async overflow both on and off and the green header seems to stick properly in Safari, STP, and WebKit trunk. Is anyone able to confirm that the is still an issue?
Comment 6 Martin Robinson 2021-09-20 00:27:49 PDT
I think this is working now, perhaps fixed by other improvements to position:sticky. I'm going to close it, but feel free to comment if it's still an issue.