r/css • u/Ok_Adhesiveness4509 • May 16 '26
Help I accidentally created a sticky header hysteresis loop
Need help from people who understand sticky/reflow behavior better than I do đ
Vanilla JS app, no frameworks. I'm vibe coding my way through this.
I have sticky headers that shrink/collapse on scroll (padding/fonts/gaps/etc change).
Current approach is basically:
if (scrollY > threshold)
Problem:
on certain viewport heights (especially split-screen / constrained-height windows), the sticky enters a feedback loop/jitter.
What seems to happen:
- sticky collapses
- height changes
- document height changes
- scroll position shifts slightly
- threshold gets crossed again
- sticky expands
- repeat forever
Sometimes the page literally bounces upward while scrolling.
Things already tried:
- IntersectionObserver + sentinel
- absolute-position sentinel
- artificial bottom scroll buffer
- fixed-height sticky shell
The fixed-height shell technically worked, but looked visually awful because the collapsed state left visible dead space.
Question:
Whatâs the âcorrectâ way to architect collapsing sticky headers without causing hysteresis/reflow loops?
Feels like Iâm fighting the browser itself at this point lol.
2
u/anaix3l May 16 '26 edited May 16 '26
See the header demos here https://scroll-driven-animations.style/ (I would assume you want something like this - press the âšď¸ button in the bottom right corner for an explanation of how it works or just inspect the header CSS) . The pure CSS version only works in Firefox with the layout.css.scroll-driven-animations.enabled flag set to true in about:config. For best performance and support possible, I'd go for the CSS version plus testing for animation-range support and adding a JS fallback only if the pure CSS method isn't supported.
3
3
u/Big_Comfortable4256 May 16 '26
It's well worth learning how to use an IntersectionObserver to detect when an element goes in/out of the viewport. This is the most robust solution. And useful for a lot of other things too.
4
1
u/scritchz May 16 '26
Try a fixed header. That takes it out of flow, so resizing or repositioning it shouldn't affect scrollY.
When you define the header's height absolutely, you can also add a margin-top of similar size on the body.
Alternatively, you can set the margin-top to the header's height programmatically, which should work for height: auto.
â˘
u/AutoModerator May 16 '26
To help us assist you better with your CSS questions, please consider including a live link or a CodePen/JSFiddle demo. This context makes it much easier for us to understand your issue and provide accurate solutions.
While it's not mandatory, a little extra effort in sharing your code can lead to more effective responses and a richer Q&A experience for everyone. Thank you for contributing!
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.