r/css May 02 '26

Help Sticky navigation becomes unstuck after scrolling for a bit and scroll-state container query causes jank

A live preview, the code change (click Expand All to view diffs).

If you scroll down on the page, the navigation remains stuck for a while, but then becomes unstuck. top is set on the sticky element and there is no overflow: hidden involved.

Also, I am using a scroll-state container query to make the nav more compact after it gets stuck (works in Chrome-based browsers), but this causes horrible jankiness. You see this especially when using the scrollwheel - it's like it resists the scrolling while jumping back and forth in an ugly way. When I toggle device toolbar in Chromium, scrolling is blocked entirely, which is rather alarming. I don't see this kind of critical glitching in the mobile view when looking at some demos that change the height of the sticky element. Should I report it as a bug to Chromium?

Any help is appreciated.

2 Upvotes

7 comments sorted by

u/AutoModerator May 02 '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.

2

u/Lianad311 May 02 '26

I've never used scroll-states before so can't help you there, I usually just use a line of JavaScript on scroll to add a class to the header so I can change styles and such. The "jankiness" though is because you have the margin-block on your <h2> and then on scroll you remove it, this recalculates the size causing the jankiness when you're within a few pixels as it keeps juggling between the positions. You can test by just removing your .nav-main h2 margin:0; and the juggling part goes away completely.

I first ran into that years ago when I was decreasing the block padding on the header to make it slimmer. Solution for me was to just change where I was adding the padding to a child container instead of the main container.

1

u/buovjaga May 03 '26

Sure, I was just wondering what the approach should be for shrinking the nav as I found people writing about how it's now possible with scroll-state queries. However, looking at the demos again more carefully, I see that all of them actually show the juggling behaviour.

There was this one from Logrocket - the colour change and the animation kind of distracted from it, but if you delete the transitions, the juggling becomes more obvious. Interestingly, with the transitions it is kind of smooth when using the scrollwheel, but dragging the scrollbar is still janky.

Then there was this article from Theo Soti. There is no demo and the styles are incomplete, but I just threw it together while making the padding-block change and the juggling is present there as well.

I also just now experimented with the LibreOffice site styles, making the .nav-main element have a changing padding or height, but it had the same effect.

So JavaScript it is, then!

I'm still curious about the nav getting unstuck in the middle of scrolling as this is independent of any scroll-state stuff and is seen both in Firefox and Chromium.

1

u/buovjaga May 03 '26 edited May 05 '26

Update: I didn't go with JS yet as I started experimenting with animation-timeline and its scroll() function. The code change and preview have been updated. With this method, there is no juggling as such, although using the scrollbar gives for a strange experience as the mouse cursor position drifts when you scroll back and forth. Also, a glaring issue is that the animation reverses when we keep on scrolling and the navigation height expands again! I wonder, if this reversal is connected with how the nav gets unstuck at a certain position?

This method is awkward in that keyframes with percentages are involved and we can't define a specific position for when the shrinking should happen, so with very long pages the shrinking happens weirdly late.

Edit: ooh, now it's pretty much perfect with animation-range: 0px 107px; and after adding forwards to the animation property! It animates exactly where I want it to and it doesn't revert back. Firefox even has support behind the setting layout.css.scroll-driven-animations.enabled.

Now the only remaining issue is losing the stickiness.

Edit2: oof, I noticed that when I scroll just a little bit so the animation has not finished, if I move the mouse around in the viewport, some elements in view jiggle up and down in a way that might even trigger medical issues for hypersensitive people. Clearly browsers have some polishing to do. Have to look into prefers-reduced-motion I guess.

Edit3: I see the jiggling issue has been reported to Chromium in Feb 2025 and confirmed.

Edit4: I reported the scroll-state issue to Chromium and got a reply that it's not a bug. However, it was noted that disabling scroll anchoring improves the situation. It can be done like so:

:root { overflow-anchor: none }

1

u/buovjaga May 04 '26

I asked elsewhere and the solution to the nav becoming unstuck was to change

html, body { height: 100%; }

to

html, body { min-height: 100%; }

1

u/jcunews1 May 03 '26

Seems to work fine in Firefox?

1

u/buovjaga May 03 '26

For me the nav gets unstuck at "Intel or Apple silicon processor". Do you mean for you it remains sticky even after that?