Skip to content

[BUGFIX] Follow scrolling of inner containers in the spotlight - #162

Merged
Kanti merged 2 commits into
bugfix/spotlight-scroll-only-for-stickyfrom
bugfix/spotlight-scroll-containers
Nov 9, 2026
Merged

Kanti merged 2 commits into
bugfix/spotlight-scroll-only-for-stickyfrom
bugfix/spotlight-scroll-containers

Conversation

@Kanti

@Kanti Kanti commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #161. Switch the base to main after #161 is merged.

Problem

The hole of a target inside an inner scroll container (an element with overflow: auto/scroll, e.g. a scrolling wrapper or body as scroll container) stayed in place when the container scrolled, because scroll events of elements do not bubble to window. The overlay then covered the moved target, and its old place was clickable. A target scrolled out of its container also opened a hole over the content outside the container. 1.10.4 behaved the same, so this is an improvement, not a regression fix.

Implemented behavior

  • The scroll listener is registered with document.addEventListener('scroll', …, {capture: true, passive: true}), which catches scrolling of the document and of elements, and removed with the matching capture.
  • Targets inside a scrollable ancestor (overflow-x or overflow-y is auto, scroll or overlay and the content is larger than the element), except document.scrollingElement, depend on scrolling like sticky and fixed targets ([BUGFIX] Only follow scrolling for sticky and fixed spotlight targets #161). This is still checked when the targets are selected; without such targets, scrolling runs no code.
  • The root element, and body while its overflow applies to the viewport (html without overflow, e.g. body {overflow-x: hidden}), are no inner scroll containers.
  • The holes of these targets are clipped to the visible area of their scroll containers, so a target scrolled out of its container opens no hole outside of it. Scroll containers around a fixed element are ignored, because they neither move nor clip it.
  • Known limits: a container that becomes scrollable later without a class or style change, e.g. by content that loads into it, is only noticed with the next selection of the targets (resize, mutation of a target). Scroll containers inside shadow roots are detected, but their scroll events do not reach the document, so their holes do not follow yet.

Tests

  • spotlight-overlay.test.js (browser), with a height: 300px; overflow: auto container:
    • After scrolling the container, the highlighted element receives the click, while the element next to it and the content below the container stay blocked. Fails without the fix.
    • A target scrolled out of the container opens no hole over the content below the container. Fails without the fix.
  • With html, body {height: 100%} body {overflow-x: hidden}, highlighted elements below the first screen stay clickable after scrolling the page. Fails without the fix for body.
  • With body as scroll container (html {overflow: hidden}), the holes follow the scrolling of body. This test guards the fix for body and passes before it as well.
  • The tests from [BUGFIX] Only follow scrolling for sticky and fixed spotlight targets #161 (static targets without getBoundingClientRect calls while scrolling, sticky and fixed targets, header fixed by a script) stay green.
  • npm run test: 97 passing, npm run lint

@Kanti
Kanti added this pull request to stack #163 November 9, 2026 15:53
@Kanti
Kanti marked this pull request as ready for review November 9, 2026 15:55
Kanti added 2 commits November 9, 2026 17:22
Scroll events of elements do not bubble to window, so the holes of
targets in an inner scroll container, e.g. a scrolling wrapper or body
as scroll container, stayed in place when the container scrolled. The
overlay then covered the moved target, and its old place was
clickable. A target scrolled out of its container also opened a hole
over the content outside the container.

The scroll listener captures the scroll events at the document, and
targets in an inner scroll container count as depending on scrolling.
Their holes are clipped to the visible area of their scroll containers.
The overflow of body applies to the viewport while html has none, e.g.
with the common `body {overflow-x: hidden}`. body then counted as inner
scroll container: every hole was clipped to the box of body, and with
`html, body {height: 100%}` targets below the first screen could not be
clicked anymore.

The root element and body with an overflow that applies to the viewport
are no inner scroll containers anymore. body as real scroll container,
with an overflow on html, still is.
@Kanti
Kanti force-pushed the bugfix/spotlight-scroll-containers branch from 18ee528 to 6acd167 Compare November 9, 2026 16:29
@Kanti
Kanti merged commit 06bd487 into main Nov 9, 2026
33 checks passed
@Kanti
Kanti deleted the bugfix/spotlight-scroll-containers branch November 9, 2026 16:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant