Search code examples
angular-materialtoolbarstickyangular8

Angular Material Sticky Toolbar - Content is Jumping when Scrolling


I have a transparent mat-toolbar with absolute position. When I scroll the page, I make the transition to the sticky class. Which is working, but when the sticky class is applied the content jumps.

When I scroll back the class change normally without problem.

<mat-sidenav-container fxFlexFill>
    <mat-sidenav-content #content cdkScrollable fxLayout="column" fxFlexFill>
    <!-- Add Content Here -->
    <mat-toolbar color="primary" class="fixed" #toolBara>
      <mat-toolbar-row>TesteNav</mat-toolbar-row>
    </mat-toolbar>
    <img src="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/549e9b77-4c90-4c7f-8d0e-772a4ba70576/d6cz757-170fb93c-919b-470a-b156-b836e67fc3fb.jpg/v1/fill/w_1192,h_670,q_70,strp/island_night_by_arsenixc_d6cz757-pre.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTA4MCIsInBhdGgiOiJcL2ZcLzU0OWU5Yjc3LTRjOTAtNGM3Zi04ZDBlLTc3MmE0YmE3MDU3NlwvZDZjejc1Ny0xNzBmYjkzYy05MTliLTQ3MGEtYjE1Ni1iODM2ZTY3ZmMzZmIuanBnIiwid2lkdGgiOiI8PTE5MjAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.Z9WO9X7AblXH_hpq7Lh2bMUcJNvQiK0Vlq6PXSjehbQ"/>
    <p *ngFor="let content of fillerContent">{{content}}</p>
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>
import { Component, AfterViewInit, ViewChild } from '@angular/core';
import { OverlayContainer, CdkScrollable, ScrollDispatcher } from '@angular/cdk/overlay';
import { MatSidenavContainer, MatToolbar, MatSidenavContent } from '@angular/material';

@Component({
  selector: 'app-my-nav',
  templateUrl: './my-nav.component.html',
  styleUrls: ['./my-nav.component.css']
})
export class MyNavComponent implements AfterViewInit { 

  @ViewChild(MatSidenavContainer, {static: true }) sidenavContainer: MatSidenavContainer;
  @ViewChild(CdkScrollable, {static: true }) scrollable: CdkScrollable;
  @ViewChild(MatSidenavContent, { static: true }) content: MatSidenavContent;
  @ViewChild('toolBara', {static: true }) toolbar: MatToolbar;

  fillerContent = Array(50).fill(0).map(() =>
  `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
    labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
    laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in
    voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
    cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`);

  constructor(public scroll: ScrollDispatcher) {}

  ngAfterViewInit() {
    this.scrollable.elementScrolled().subscribe(() => {
      const scrollTop = this.sidenavContainer.scrollable.getElementRef().nativeElement.scrollTop;
      if (scrollTop > 0) {
        this.toolbar._elementRef.nativeElement.classList.add('sticky');
        this.toolbar._elementRef.nativeElement.classList.remove('fixed');
        console.log('SCroll', "sticky");
      } else {
        this.toolbar._elementRef.nativeElement.classList.add('fixed');
        this.toolbar._elementRef.nativeElement.classList.remove('sticky');
        console.log('SCroll', "fixed");
      }
    });
  }
}

.mat-toolbar.mat-primary {
  -webkit-transition: 700ms ;
  -ms-transition:  700ms ;
  transition: 700ms ;
  -webkit-animation: sk-bounce 2.0s infinite ease-in-out;
  animation: sk-bounce 2.0s infinite ease-in-out;
}
.fixed {
  position: absolute;
  background-color: transparent !important;
  top: 0;
  z-index: 5;
  margin-top: 0.90%;
  align-content: center;
  color: #fff;
}
.sticky {
  position: sticky;
  position: -webkit-sticky;
  top: 0;
  z-index: 5;
}
img {
  height: 120px;
}

I wonder what I am doing wrong that is making the content jumping when I scroll.

Stackblitz here: https://stackblitz.com/edit/angular-stfgjd


Solution

  • I found the solution. Just posting here to maybe help others in the future. The thing is to put the toolbar after the router-outlet. This way it works nicelly.

    https://stackblitz.com/edit/angular-stfgjd

    *Details on the link.