2

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.

Joe Allen
  • 1,267
  • 4
  • 24
  • 41
  • Can you create a demo link and share it? – uiTeam324 Apr 14 '20 at 08:19
  • This Q related to your issue? https://stackoverflow.com/questions/487073/how-to-check-if-element-is-visible-after-scrolling. 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 - http://imakewebthings.com/waypoints/ - package: https://www.npmjs.com/package/angular-waypoints – Ezra Siton Apr 14 '20 at 08:24
  • You talk about a sidenav in your question. Where is it? Is it important at all? – julianobrasil Apr 14 '20 at 08:48
  • 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 Apr 14 '20 at 09:33
  • Demo link : 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. – Joe Allen Apr 14 '20 at 10:33

2 Answers2

7

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

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • Thank you very much for your help but I have a last question, how the nav-menu could move to right or left depends on active item ? Thank you again :) – Joe Allen Apr 14 '20 at 12:44
  • Do you mean how to highlight active menu item while scrolling? – yurzui Apr 14 '20 at 12:57
  • I would like my sticky menu (with mat-chips) shift to right or left to still see the active category, for example, if one scrolls down the items list, I would like to see the according nav item be fully displayed – Joe Allen Apr 14 '20 at 13:23
  • You can use `transform: translateX` rule on `mat-chips-list` element to shift items https://monosnap.com/file/MKSEhmQe5IDohPSDoICMZxkj11Yq6j – yurzui Apr 14 '20 at 13:32
  • I'm not sure if it's the solution. When I have too many nav items, I can scroll to the right. But it's not automatic if the user scrolls down the content, the active item is not shown. If the user scrolls down, the nav-menu scroll automatically on active nav-item. Hope I was more understandable – Joe Allen Apr 14 '20 at 14:01
  • You need to make it automatic so that when user scrolls menu is scrolled to that active item – yurzui Apr 14 '20 at 14:03
  • yep exactly :) but when I tried transform solution, I have got the menu cutted 100px from right border (tested on mobile) – Joe Allen Apr 14 '20 at 14:11
  • It will be cut anyway. There is another way: use mat-tab-nav-bar like here https://stackblitz.com/edit/angular-zywvjy?file=src/app/app.component.ts – yurzui Apr 14 '20 at 14:20
  • Here's an example https://stackblitz.com/edit/angular-9-0-0-rc-1-s68vgh?file=src%2Fapp%2Fpages%2Fcontent%2Fcontent.component.scss and I will share preview in my answer – yurzui Apr 14 '20 at 14:49
  • It's a good solution for desktop but not exactly what I want for my mobile web app. Is it possible to remove chevrons ? Morever, how could it active automatically nav item when user scrolls down (if the user sees item 4, nav item 4 is active) ? Thank you very much for your help ! – Joe Allen Apr 14 '20 at 16:11
  • If you checked my demo https://stackblitz.com/edit/angular-9-0-0-rc-1-s68vgh?file=src%2Fapp%2Fpages%2Fcontent%2Fcontent.component.scss then you might notice that active item changes depending on scroll position. Yes, you can remove chevrons. Anyway, we moved far from the original question – yurzui Apr 14 '20 at 16:20
0

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

Nadhir Houari
  • 390
  • 4
  • 10