Open
Description
Is this a regression?
- Yes, this behavior used to work in the previous version (I don't know)
The previous version in which this bug was not present was
No response (I don't know)
Description
I switched from the basic version to experimental because we need to support various item sizes, and encountered this during implementation.
When using the CDK virtual scroller with autosize, a visual glitch occurs after resizing the viewport width (or zooming in/out) and scrolling to the bottom of the content.
- Attempting to scrolling back up, the translateY property becomes negative, and just keeps getting lower and lower, unable to recover with any scroll attempt. It seems like any mouse wheel scroll attempt just registers as "scroll down" and keeps increasing the already out-of-bound value.
- With my workaround that prevents translateY from becoming negative, the viewport is still glitchy. Scrolling up (and up only) is causing the viewport content to disappear and reappear in a glitchy manner. This glitch only happens after scrolling to the BOTTOM of the content after resizing the viewport (or window if it snaps to it), and it persists until the user scrolls to the exact TOP of the viewport. After you scroll completely to the top (with the workaround implemented), the glitchy behavior stops, you can scroll up and down, even to the bottom, and it will work, until the viewport width is resized again, and then the glitch reappears.
- The workaround-glitch does not start happening (nor the one without the workaround) until you actually scroll to the bottom. if you just scroll to the middle, etc, and then up, it behaves normally.
Unfortunately the workaround is not enough and results in horrible UX, especially with large datasets.
Snippets:
Template:
<cdk-virtual-scroll-viewport
#accordionVirtualScroller
autosize
[style.height]="isOutermostInstance ? '100%' : '500px'"
(scroll)="checkViewportStuff($event)"
>
... rendered a bunch of closed accordions etc ...
</...>
Component:
checkViewportStuff($event: Event): void {
console.log('well, we scrolled');
const accordionWrapper = this.accordionVirtualScroller.elementRef.nativeElement;
const contentWrapper = accordionWrapper.querySelector('.cdk-virtual-scroll-content-wrapper') as HTMLElement;
if (!contentWrapper) return;
const transformStyle = contentWrapper.style.transform;
const translateYMatch = transformStyle.match(/translateY\(([^)]+)\)/);
if (translateYMatch && translateYMatch[1]) {
const translateY = parseFloat(translateYMatch[1]);
if (translateY < 0) {
console.log('OUT OF BOUNDS');
setTimeout(() => {
this.renderer.setStyle(contentWrapper, 'transform', 'translateY(0px)');
accordionWrapper.scrollTop = 0;
}, 100);
}
}
}
Reproduction
Steps to reproduce:
- Implement the CDK virtual scroller with autosize enabled.
- Resize the viewport width to change the width of the virtual scroller.
- Scroll to the bottom of the content.
- Attempt to scroll back up.
Expected Behavior
- Smooth scrolling without any visual glitches
- No out-of-bound translateY values.
- Correct scroll direction.
Actual Behavior
- When scrolling back up from the bottom after resizing the viewport width, the translateY CSS property becomes negative and keeps getting lower and lower, causing the viewport content to disappear.
- The viewport does not differentiate between the scroll wheel direction, it just keeps pushing the translateY further into an invalid value.
Environment
- Angular: 15.1.4, 15.2.5 (both versions tested, updated to see if it helps)
- CDK: 15.1.4, 15.2.5
- CDK-Experimental: 15.1.4, 15.2.5
- Browser(s): Brave v1.49.132 (Chromium), Mozilla 111.0.1 (64-bit), likely all other browsers?
- Operating System:: Windows 10 Enterprise 21H2