Skip to content

Fix Virtualize scroll container detection with horizontal overflow#65744

Open
ilonatommy wants to merge 2 commits intodotnet:mainfrom
ilonatommy:fix-58200
Open

Fix Virtualize scroll container detection with horizontal overflow#65744
ilonatommy wants to merge 2 commits intodotnet:mainfrom
ilonatommy:fix-58200

Conversation

@ilonatommy
Copy link
Member

@ilonatommy ilonatommy commented Mar 11, 2026

findClosestScrollContainer() incorrectly selected elements with overflow-x set to a non-visible value as the vertical scroll root.
Per the CSS spec, setting overflow-x to a non-visible value promotes overflow-y from 'visible' to 'auto', causing the heuristic to pick containers that don't actually scroll vertically.

Description

The fix adds a check that the candidate element can actually scroll vertically (scrollHeight > clientHeight) or has overflow-y explicitly set to 'scroll' before selecting it as the scroll container.

Proposal #58200 (comment) works the issue around and can be used until this fix gets in.

Fixes #58200

@ilonatommy ilonatommy added this to the .NET 11 Planning milestone Mar 11, 2026
@ilonatommy ilonatommy self-assigned this Mar 11, 2026
@ilonatommy ilonatommy requested a review from a team as a code owner March 11, 2026 16:20
Copilot AI review requested due to automatic review settings March 11, 2026 16:20
@ilonatommy ilonatommy added area-blazor Includes: Blazor, Razor Components feature-blazor-virtualization This issue is related to the Blazor Virtualize component labels Mar 11, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Blazor Virtualize’s scroll container detection so that elements whose overflow-y is only implicitly promoted (due to non-visible overflow-x) are no longer incorrectly selected as the vertical scroll root when they don’t actually scroll vertically.

Changes:

  • Update findClosestScrollContainer() to require actual vertical scrollability (or explicit overflow-y: scroll) before selecting an element.
  • Add a new BasicTestApp scenario reproducing horizontal-overflow container behavior.
  • Add an E2E test asserting Virtualize continues to load items when the container only scrolls horizontally and the page is the vertical scroll root.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/Components/Web.JS/src/Virtualize.ts Tightens scroll-root selection to avoid false positives caused by CSS overflow promotion.
src/Components/test/testassets/BasicTestApp/VirtualizationHorizontalOverflow.razor Adds a repro component exercising horizontal overflow with vertical overflow hidden.
src/Components/test/testassets/BasicTestApp/Index.razor Exposes the new repro component in the BasicTestApp selector.
src/Components/test/E2ETest/Tests/VirtualizationTest.cs Adds an E2E regression test for the horizontal-overflow container scenario.


if (style.overflowY !== 'visible') {
return element;
if (element.scrollHeight > element.clientHeight || style.overflowY === 'scroll') {
Copy link
Member

@oroztocil oroztocil Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an edge case that is not covered? If you have a container with overflow-x: auto, overflow-y: hidden, and a fixed height (e.g., 400px), the content inside is taller than the container, so scrollHeight > clientHeight is true. Even with the fix we would pick this container as the scroll root. But overflow-y: hidden means the user can't actually scroll it, so virtualization would still be broken in that scenario.

This isn't a regression, though. The old code also picked this element because its
computed overflowY was hidden, which isn't visible. A stronger fix could also exclude
hidden and clip values since those never allow user scrolling:

if (style.overflowY !== 'visible') {
    const canScroll = style.overflowY !== 'hidden' && style.overflowY !== 'clip';
    if (canScroll && (element.scrollHeight > element.clientHeight || style.overflowY === 'scroll')) {
        return element;
    }
}

Feel free to not handle this case in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-blazor Includes: Blazor, Razor Components feature-blazor-virtualization This issue is related to the Blazor Virtualize component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor Virtualize: root-level scrolling breaks on horizontal scroll enabled in the container

3 participants