components icon indicating copy to clipboard operation
components copied to clipboard

[cdk-virtual-scroll-viewport][mat-table] - sticky headers is not working properly when combining mat-table with cdk-virtual-scroll-viewport

Open kriswinbush opened this issue 5 years ago • 3 comments

Reproduction

Use StackBlitz to reproduce your issue: https://stackblitz.com/fork/components-issue https://stackblitz.com/edit/virtual-scroll-table-sticky-headers

Steps to reproduce:

  1. wrap mat-table within a cdk-virtual-scroll-viewport element
  2. add sticky: true property to *matHeaderRowDef directive as stated in documentation
  3. observe sticky header slide down the viewport after about 10 rows.

Expected Behavior

Expect when adding the sticky:true; property to mat-table *matHeaderRowDef directive wrapped within a cdk-virtual-scroll-viewport that the headers remain positioned at the top of the viewport.

Actual Behavior

As you scroll the cdk-virtual-scroll-viewport slides the entire mat-table instead of just the row contents wrapped in the tbody element.

Environment

  • Angular: >= 7
  • CDK/Material: >= 7
  • Browser(s): chrome, firefox, opera, safari
  • Operating System (e.g. Windows, macOS, Ubuntu): all

kriswinbush avatar Jan 21 '20 17:01 kriswinbush

Playing around in your stackblitz seems like it can be fixed by have a transform: translateY(-<>px); See screenshot below, when I update the .mat-header-row with a negative value in the translateY of the cdk-virtual-scroll-content-wrapper translateY element, the header seems to be correct. image

karimsacre avatar Feb 01 '20 02:02 karimsacre

I can't comment on why this bug happens as it seems to be a feature. For every few lines you scroll, the translate-y is increased. So for our use case, I added this CSS rule to fix it:

.cdk-virtual-scroll-content-wrapper
{
  transform: none !important;
}

Hope it helps.

SteGriff avatar Oct 16 '20 14:10 SteGriff

found somewhat of a fix for the problem. 96 is just the rowheight * 2

const offset = this.cdkVirtualScrollViewport.measureScrollOffset('top');
this.cdkVirtualScrollViewport.scrollToOffset(offset - 96);
asapScheduler.schedule(() => this.cdkVirtualScrollViewport.scrollToOffset(offset), 1);

niteshkhanna1989 avatar Nov 24 '22 08:11 niteshkhanna1989