I have a fix for the perennial problem with position: sticky and overflow.

Well, my perennial problem anyway.

What is the problem, Ben?

Position sticky is defined like this at MDN:

is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block (nearest block-level ancestor)

Crucial there is “nearest scrolling ancestor”.

So all works well with position: sticky until you add overflow-x: hidden to an ancestor of the sticky element because a sibling element of the sticky element needs its overflow to be hidden/scrollable (a sideways scroller for example). When you do that, the sticky element does not stick! That’s because using overflow creates a new formatting context which means that our sticky element looks to the item with overflow-x: hidden on as its reference as to whether to stick or not, and now it never will because it will never reach the top of it!

In addition, when you have no overflow-x: hidden on the body, as I often do to prevent side to side ‘rubber band’ scrolling in iOS, that can also kill your sticky element.

overflow: clip to the rescue

However, in both these situations, you can use overflow-x: clip instead and it clips as you would expect allowing the same kind of behaviours, but crucially does NOT stop sticky elements sticking because it does NOT create a formatting context. Again, from MDN:

The difference between clip and hidden is that the clip keyword also forbids all scrolling, including programmatic scrolling. No new formatting context is created.

Amazing, so happy this little piece of differentiation exists and I don’t know why it escaped me until now. I only discovered it when toggling through the overflow options in the dev tools!

Codepen Demo

Not convinced? Open this Codepen and see for yourself, the little button top left is just toggling from hidden to auto on the overflow property. Notice how the black bar sticks and unsticks?

See the Pen Position sticky AND overflow to prevent horizontal rubber-banding by Ben Frain (@benfrain) on CodePen.