2
votes

I'm trying to set two sticky divs (one header, one sidenav) using Angular Material. Sticky divs works except from scrolling event when I scroll down into my content.

enter image description here

And when I scroll down, I have something like this :

enter image description here

My problem is : When I scroll down, I haven't any scroll event from Angular. If I change style.scss file by setting a value to height css property, all sticky div doesn't work anymore BUT I have my scroll event from Angular.

It's getting to my nerve :( Any idea to solve this problem ? Thank you very much !

style.scss

html, body { 
    min-height: auto; // sticky header doesn't work but scroll event Angular OK
    // height: 100%; // sticky header works but scroll event Angular NOK
}

body { 
    margin: 0; 
    font-family: Roboto, "Helvetica Neue", sans-serif; 
}

STICKY HEADER CODE :

app.component.html

<div class="app-wrapper">
    <router-outlet></router-outlet>
</div>
app.component.scss

.app-wrapper {
    min-height: 100%;
    overflow-x: hidden;
}
.my-toolbar {
    position: sticky;
    position: -webkit-sticky; /* For macOS/iOS Safari */
    top: 0; /* Sets the sticky toolbar to be on top */
}

app-main.component.html

<mat-toolbar color="primary" class="my-toolbar">
    <mat-toolbar-row>
        <div fxFlex fxLayoutAlign="flex-start">
            <mat-icon routerLink="/home">home</mat-icon>
        </div>
        <h1>My title</h1>
    </mat-toolbar-row>
</mat-toolbar>

<router-outlet></router-outlet>

app-main.scss

.app-toolbar {
    position: sticky;
    position: -webkit-sticky; /* For macOS/iOS Safari */
    top: 0; /* Sets the sticky toolbar to be on top */
}

STICKY MENU

app-content.html

<div fxLayout="column">
    <img fxFlex="10" src="assets/test.jpg"  alt="menu picture" />

    <div class="categories nav-menu color-primary">
        <app-horizontal-nav
            [navItems]="categories$ | async">
        </app-horizontal-nav>
    </div>

   <!-- content -->
   <app-products></app-products>
</div>

app-content.scss

.nav-menu {
    position: sticky;
    position: -webkit-sticky; /* For macOS/iOS Safari */
    top: 50px; // for the first sticky header
}

EDIT :

Here a stackblitz demo : https://stackblitz.com/edit/angular-9-0-0-rc-1-zhoy51 in style.scss, change height from auto to 100% and sticky headers will works. BUT none scroll event from scrolledToDirective are fired.

2
Can you create a demo link and share it? - uiTeam324
This Q related to your issue? stackoverflow.com/questions/487073/…. You should use some Utility Function (Dedect scroll into view / Window.innerHeight and so on is part of Javascript/Web APIs Core - Not specific to angular). Or for "very complex" trigger ideas you should use a third-party plugin like this one: WayPoints.js - imakewebthings.com/waypoints - package: npmjs.com/package/angular-waypoints - Ezra Siton
You talk about a sidenav in your question. Where is it? Is it important at all? - julianobrasil
1. I'm going to add a stackblitz demo 2. I think it's more a css problem or how the html page is built but not sure. 3. Actually, the sidenav is my sticky menu. - Joe Allen
Demo link : stackblitz.com/edit/angular-9-0-0-rc-1-zhoy51 in style.scss, change height from auto to 100% and sticky headers will works. - Joe Allen

2 Answers

6
votes

You have the following rule on your main wrapper:

.app-wrapper {
    height: 100%; // doesn't have any effect since parent's(app-root) height is 0 
    overflow-x: hidden; <== remove this
}

Once you set 100% to the body you moved scroll to that wrapper.

You should remove overflow-x: hidden; and it should work. But there will be still a small issue with horizontal scroll which is caused by material mat-chip-list, so add overflow: hidden there:

.nav-menu {
    ...
    overflow: hidden;  <==== this one
}

Forked Stackblitz

enter image description here

0
votes

Add simply this <body style="height: 100vh!important;" to your index.html.