Started recently learning material 2 and ran to issue. My approach is to do a sidenav as in Youtube
website. There is a hamburger menu on left which expands/collapses side menu.
Code:
<md-toolbar class="fixed-header">
<button class="app-icon-button" (click)="start.toggle()">
<i class="material-icons app-toolbar-menu">menu</i>
</button>
</md-toolbar>
<md-sidenav-container>
<md-sidenav #start class="app-sidebar" mode="side">test</md-sidenav>
<div class="text">
{{ text }}
</div>
</md-sidenav-container>
Now seems like I achieved the layout, but the positioning is not fixed
, if i scroll toolbar
moves and sidenav
content also moves.
Edit:
On angular material documentation I later found the example which one I have been looking for:
https://stackblitz.com/angular/rmjxrpxdgmx?file=app%2Fsidenav-responsive-example.html
if link will be removed, here is the code:
HTML File:
<div class="example-container" [class.example-is-mobile]="mobileQuery.matches" *ngIf="shouldRun">
<mat-toolbar color="primary" class="example-toolbar">
<button mat-icon-button (click)="snav.toggle()"><mat-icon>menu</mat-icon></button>
<h1 class="example-app-name">Responsive App</h1>
</mat-toolbar>
<mat-sidenav-container class="example-sidenav-container"
[style.marginTop.px]="mobileQuery.matches ? 56 : 0">
<mat-sidenav #snav [mode]="mobileQuery.matches ? 'over' : 'side'"
[fixedInViewport]="mobileQuery.matches" fixedTopGap="56">
<mat-nav-list>
<a mat-list-item routerLink="." *ngFor="let nav of fillerNav">{{nav}}</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<p *ngFor="let content of fillerContent">{{content}}</p>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
TS File:
import {MediaMatcher} from '@angular/cdk/layout';
import {ChangeDetectorRef, Component, OnDestroy} from '@angular/core';
/** @title Responsive sidenav */
@Component({
selector: 'sidenav-responsive-example',
templateUrl: 'sidenav-responsive-example.html',
styleUrls: ['sidenav-responsive-example.css'],
})
export class SidenavResponsiveExample implements OnDestroy {
mobileQuery: MediaQueryList;
fillerNav = Array.from({length: 50}, (_, i) => `Nav Item ${i + 1}`);
fillerContent = Array.from({length: 50}, () =>
`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.`);
private _mobileQueryListener: () => void;
constructor(changeDetectorRef: ChangeDetectorRef, media: MediaMatcher) {
this.mobileQuery = media.matchMedia('(max-width: 600px)');
this._mobileQueryListener = () => changeDetectorRef.detectChanges();
this.mobileQuery.addListener(this._mobileQueryListener);
}
ngOnDestroy(): void {
this.mobileQuery.removeListener(this._mobileQueryListener);
}
}
CSS File:
.example-container {
display: flex;
flex-direction: column;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.example-is-mobile .example-toolbar {
position: fixed;
/* Make sure the toolbar will stay on top of the content as it scrolls past. */
z-index: 2;
}
h1.example-app-name {
margin-left: 8px;
}
.example-sidenav-container {
/* When the sidenav is not fixed, stretch the sidenav container to fill the available space. This
causes `<mat-sidenav-content>` to act as our scrolling element for desktop layouts. */
flex: 1;
}
.example-is-mobile .example-sidenav-container {
/* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the
`<body>` to be our scrolling element for mobile layouts. */
flex: 1 0 auto;
}
Best Answer
To keep the toolbar on top, use
position: fixed
andz-index: 999
. To keep thesidenav
outside of scrollable area, it needs to be taken outside ofmd-sidenav-container
Thanks for creating a the plnkr demo, it helped a lot to quickly find a solution. Here's the modified demo.
app.component.html:
app.component.css:
Let me know if that's what you are looking for.