[BUGFIX] Fix sticky header scroll flicker in Chromium browsers#1618
Open
CybotTM wants to merge 8 commits into
Open
[BUGFIX] Fix sticky header scroll flicker in Chromium browsers#1618CybotTM wants to merge 8 commits into
CybotTM wants to merge 8 commits into
Conversation
The hardcoded 120px scroll threshold causes a feedback loop in Chromium browsers: at the threshold, adding navbar-transition changes the navbar height (position:sticky), which shifts document content, which changes scrollY, which toggles the class back, creating constant flickering. Replace the hardcoded threshold with getBoundingClientRect().bottom which dynamically adapts to the actual navbar height. Additionally, check classList.contains() before toggling to prevent redundant DOM mutations. Resolves: benjaminkott#1424 Resolves: benjaminkott#1468
The JS workaround is no longer needed. The root cause (document height instability) is fixed in _transition.scss by compensating with margin-bottom.
The navbar uses position:sticky, so height changes affect document flow. When navbar-transition reduces --mainnavigation-nav-height to the xs value (70px), the document shrinks, causing scrollbar jumps and scroll-position oscillation in Chromium browsers. Add compensating margin-bottom computed from $navbar-heights map: the difference between each breakpoint's default height and the transition height (xs). This keeps document height constant while the navbar still visually shrinks. Resolves: benjaminkott#1424 Resolves: benjaminkott#1468
Restores the JS fix that was incorrectly reverted. This PR addresses the scroll flicker symptom via dynamic threshold.
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The sticky navigation bar flickers when scrolling through the transition zone in Chromium-based browsers (Chrome, Edge). This has been reported in #1424 and #1468, affects the official demo site, and has been open since January 2024.
Root cause
bootstrap.stickyheader.jsuses a hardcoded120pxscroll threshold:Since
.navbar-fixed-topusesposition: sticky, the navbar stays in document flow. Whennavbar-transitionis added,--mainnavigation-nav-heightchanges from the responsive default (100-110px on desktop) to 70px. This height reduction shifts document content upward, which changesscrollY, which can drop it back below 120px, removing the class, restoring the height, shifting content back down — creating a feedback loop.Fix
Two changes:
Replace hardcoded
120pxwithgetBoundingClientRect().bottom— dynamically adapts to the actual navbar height at any breakpoint, so the threshold matches the element's real position.Check
classList.contains()before toggling — prevents redundant DOM mutations when the class is already in the desired state.Why this works
getBoundingClientRect().bottomreturns the navbar's current bottom edge relative to the viewport. Withposition: sticky; top: 0, this equals the navbar's current height.navbar-transition),bottomequals the full height (e.g., 110px). The class is only added oncescrollYexceeds this value.navbar-transitionis active and the navbar has shrunk,bottomequals the reduced height (70px). The class is only removed whenscrollYdrops below this smaller value.Note: An alternative CSS-only approach exists (see #1619) that fixes the root cause (document height instability) rather than the symptom. Both approaches are valid and can be combined.
Credit: Solution based on community contributions in #1468 by @howie-f, @danscheer, and @SventB.
Resolves #1424
Resolves #1468
Prerequisites