fix(sidebar): prevent docs page scrolling when typing in the sidebar filter#34
Merged
Merged
Conversation
…scroll-into-view Replace the 15-frame rAF scroll-lock with a leaner combo: disable smooth scroll while the input has focus (so the unwanted scroll is a single instant jump, not a 250ms animation) and pin scrollY for ~200ms after each keystroke, extending the window on held-key repeats to cover Lit's batched re-renders.
510e011 to
f14b67f
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Workaround for a Chromium-only quirk where typing in the sidebar's igc-input filter (rendered inside a position: sticky sidebar) triggers a browser-internal "scroll focused editable into view" pass that visibly scrolls the docs page upward on each keystroke. The fix is scoped to sidebar-filter.ts and intentionally avoids restructuring layout.
Changes:
- While the filter input has focus, force
scroll-behavior: auto !importanton<html>(overrides a third-partysmooth !important), and clear it on blur. - New
pinScrollY()helper captureswindow.scrollYand snaps it back via rAF for ~10 frames; held-key repeats extend the same loop instead of stacking parallel ones. - Call
pinScrollY()at the top ofonFilterInput,onFilterKeydown, andresetFilterto cover typing, Escape, Backspace/Delete repeat, and clear-button paths.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Previously the focus-time scroll-behavior toggle didn't cover the X clear button (focus leaves the input before resetFilter runs, restoring smooth mid-mutation and causing a visible stutter). Move the toggle into pinScrollY itself so 'auto' is in effect for exactly the pin window, regardless of focus state. Prior inline value (DocsLayout's 'smooth') is restored when the window ends.
ChronosSF
approved these changes
May 29, 2026
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.
Closes: #28
Closes: IgniteUI/igniteui-documentation#253
Summary
Fixes the sidebar filter input scrolling the docs page back toward the top on every keystroke (and on X-button click, Escape, held-Backspace, held-Delete) when the user has scrolled the page down.
Root cause (empirically confirmed)
Chrome runs an internal "scroll the focused editable into view" pass on every input mutation. Two facts conspire to make it visible in this layout:
<igc-input>lives inside aposition: stickysidebar. Visually it sits at the top of the viewport, but in the layout tree its document-flow position is wherever the sidebar would naturally be, i.e. above the viewport once the page is scrolled down.scroll-behavior: smoothon<html>(set byDocsLayout'sastro:page-loadhandler), the disagreement manifests as a smooth-animated scroll upward. Withscroll-behavior: auto, the same code path still fires but as a single instant jump (~one row height per keystroke), which compounds across held keys.This was verified by running
document.documentElement.style.scrollBehavior = 'auto'in DevTools (animation gone, jumps still measurable aswindow.scrollYdecreased by ~54px per keystroke).What this is not
Ruled out via DevTools / instrumentation:
scroll-marginoroverflow-anchor(CSS tweaks tried, bug persists).scrollTo,scrollIntoView, andscrollTopsetters were instrumented and produced no stack frames. The scroll is entirely browser-internal.overflow-anchor: none).How we handle it
A small, focused workaround in
sidebar-filter.ts:pinScrollY()saveswindow.scrollYand snaps back every frame for ~200ms viarequestAnimationFrame. rAF runs after layout but before paint, so the snap beats any visible scroll. Called at the top ofonFilterInput,onFilterKeydown, andresetFilter. Held-key repeats extend the pin window in place (single loop, not parallel) so cascading Lit re-renders afterexitFilterModeare also covered.pinScrollYalso setsscroll-behavior: auto !importanton<html>so the unwanted scroll is a single instant jump rather than a 250ms smooth animation that the pin would have to fight every frame (which caused visible stutter). The prior inline value is restored when the window ends, preserving DocsLayout'sscroll-behavior: smoothfor in-page anchor scrolling.!importantis required because a third-party stylesheet setsscroll-behavior: smooth !important(confirmed viagetComputedStyle).Why not a cause-level fix
Empirically ruled out:
scroll-margin-top: -9999pxon<igc-input>host and::part(input). The caret-visibility pass ignoresscroll-marginhere.overflow-anchor: noneon<html>and*. Confirmed applied, bug persists.Element.prototype.scrollIntoView. No JS calls in the scroll stack.html:has(igc-input[data-sidebar-filter-input]:focus-within) { scroll-behavior: auto !important }).:focus-withinon the host did not cross theigc-inputshadow boundary reliably in our testing.position: fixed. Works but requires JS geometry sync against the grid column width and breaks on responsive breakpoints. Not worth the blast radius for a Chrome-only quirk.Test plan