Skip to content

Conversation

dariatiurina
Copy link
Contributor

@dariatiurina dariatiurina commented Oct 13, 2025

Fix the bug with scrolling in Virtualize component with scaled elements

Description

This pull request improves the Virtualize component’s handling of CSS scaling and transforms, ensuring correct virtualization behavior when parent elements use scale, zoom, or transform properties. It also adds new test to verify these changes.

The issue was caused by inconsistent scaling algorithm between JS and C#. JS used to send scaled size values to C# while C# logic assumes they are not scaled. This PR standardizes the sizes before sending to reflect non-scaled values.

Changes:

  • Updated Virtualize.ts to detect and correctly handle CSS scale, zoom, and transform properties on parent elements, adjusting scroll calculations so virtualization works accurately under scaling scenarios.
  • Added a new test CanScrollWhenAppliedScale to verify that virtualization works when CSS scale is applied.

Fixes #59354

@github-actions github-actions bot added the area-blazor Includes: Blazor, Razor Components label Oct 13, 2025
@dariatiurina dariatiurina self-assigned this Oct 13, 2025
@dariatiurina dariatiurina marked this pull request as ready for review October 13, 2025 14:56
@dariatiurina dariatiurina requested a review from a team as a code owner October 13, 2025 14:56
@Copilot Copilot AI review requested due to automatic review settings October 13, 2025 14:56
Copy link
Contributor

@Copilot 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 a bug in the Virtualize component where scroll calculations were incorrect when CSS scaling transforms were applied to parent elements. The issue occurred because the component used physical pixel measurements without accounting for scale factors.

  • Adds scale factor detection and compensation logic to handle CSS scale, zoom, and transform properties
  • Converts physical pixel measurements to logical pixels for accurate virtualization calculations
  • Includes test coverage for the scaling scenario with a new E2E test

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
VirtualizationScale.razor New test component demonstrating virtualization with CSS scale applied to body
QuickGridVirtualizeComponent.razor Fixes items provider to respect pagination parameters
Index.razor Adds new test component to navigation options
VirtualizationTest.cs Adds E2E test to verify virtualization works with scaling
Virtualize.ts Core fix - adds scale factor detection and applies compensation to scroll calculations

Copy link
Member

@ilonatommy ilonatommy left a comment

Choose a reason for hiding this comment

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

Good job! The comments are mostly optional changes/questions.

rangeBetweenSpacers.setStartAfter(spacerBefore);
rangeBetweenSpacers.setEndBefore(spacerAfter);
const spacerSeparation = rangeBetweenSpacers.getBoundingClientRect().height;
const rangeRect = rangeBetweenSpacers.getBoundingClientRect();
Copy link
Member

Choose a reason for hiding this comment

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

This change is redundant, rangeRect is not used anywhere.


<style>
body {
scale: 2 0.5;
Copy link
Member

Choose a reason for hiding this comment

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

Because in the algo we focus on y-axis value, the tests check mainly 50% scaling (decreasing). Would such an approach work, so that we can test increasing and decreasing cases?

@code {
    [Parameter]
    public double ScaleX { get; set; } = 1.0;
    [Parameter]
    public double ScaleY { get; set; } = 1.0;
}

<style>
    body {
             scale: @ScaleX, @ScaleY;
             transform-origin: top left;
     }
</style>

I'm not sure how to pass these params to the component, though. The component is mounted directly, not navigated to. Maybe we can add path to it and then use SetUrlViaPushState("/path?scaleX=1&scaleY=1"); to pass the query values?

Skip if it's too much test logic changes and you tested both cases. We can always add additional tests after the fix lands.

const computedStyle = getComputedStyle(element);

// Check for zoom property (applies uniform scaling)
if (computedStyle.zoom && computedStyle.zoom !== 'normal' && computedStyle.zoom !== '1') {
Copy link
Member

Choose a reason for hiding this comment

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

We have a check for:

  • zoom
  • scale
  • transform

DOM size can be also changed using width/height directly. Does it also affect the scrolling?

const computedStyle = getComputedStyle(element);

// Check for zoom property (applies uniform scaling)
if (computedStyle.zoom && computedStyle.zoom !== 'normal' && computedStyle.zoom !== '1') {
Copy link
Member

Choose a reason for hiding this comment

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

It's interesting that getComputedStyle.zoom returns strings. Zoom property accepts integers or decimals. Is there any chance for it to return "1.0" when we set it in a float-like way?

}

[Fact]
public void CanScrollWhenAppliedScale()
Copy link
Member

Choose a reason for hiding this comment

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

Would this fail without the change? The check that I used for detecting the glitch was much more complex. Some solutions did not prevent the full loading of data but still, resulted in the glitch on the way to the bottom.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Blazor Virtualize Feature Bug with Scaled Elements Causing Scroll Errors

2 participants