Липкий материал панели инструментов 2 и сиденав
Недавно начал учебный материал 2 и побежал к выпуску. Мой подход заключается в том, чтобы сделать sidenav как в Youtube
Веб-сайт. Слева находится меню гамбургера, которое расширяет / сворачивает боковое меню. Код:
<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>
Теперь кажется, что я достиг макета, но позиционирование не fixed
если я прокручиваю toolbar
движется и sidenav
Содержание также движется.
Edit:
В документации по угловым материалам я позже нашел пример, который искал:
https://stackblitz.com/angular/rmjxrpxdgmx?file=app%2Fsidenav-responsive-example.html
если ссылка будет удалена, вот код:
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;
}
3 ответа
Чтобы держать панель инструментов сверху, используйте position: fixed
а также z-index: 999
, Чтобы сохранить sidenav
за пределами области прокрутки, его нужно брать за пределы md-sidenav-container
Спасибо за создание демоверсии plnkr, она очень помогла быстро найти решение. Вот модифицированная демка.
app.component.html:
<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 >
<div class="text" style="min-height: 99vh">
{{ text }}
</div>
</md-sidenav-container>
<md-sidenav #start class="app-sidebar side-nav-style" mode="side" >
test
</md-sidenav>
app.component.css:
.fixed-header {
top: 0;
position: fixed;
z-index:999;
}
.text {
width: 5px;
}
.side-nav-style{
background-color: grey;
width: 6em;
margin-top:62px;
position: fixed
}
Дайте мне знать, если это то, что вы ищете.
@Nehal у примера все еще есть проблема, где <md-sidenav-container>
находится под верхней панелью инструментов, показанной здесь в обновленном plnkr:
https://plnkr.co/edit/vXB6aUoJCkx8tAJkelbF?p=preview
Если вы следуете официальным документам Angular, посмотрите пример "Fixed sidenav" по ссылке ниже, вы должны получить желаемый вид с липкой панелью инструментов.
https://material.angular.io/components/sidenav/examples
Пример полного стекаблица:
https://stackblitz.com/angular/qdpqnrlnpom?file=app%2Fsidenav-fixed-example.ts
У меня такая же проблема. Я исправил это с помощью встроенного CSS. Теперь у меня есть:
- исправлен заголовок панели инструментов
- фиксированный, прокручиваемый SideNav
- прокручиваемый контент
Вот код:
<div style="position:absolute; top:0; bottom:0; left:0; right: 0; display: flex; flex-direction: column;">
<mat-toolbar color="primary">
<button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
TOOLBAR
</mat-toolbar>
<mat-sidenav-container style="flex: 1;">
<mat-sidenav mode="side" opened="true" #sidenav>
SIDENAV
</mat-sidenav>
<mat-sidenav-content>
CONTENT
</mat-sidenav-content>
</mat-sidenav-container>
</div>
Может быть, кто-то может оптимизировать мой плохой CSS, используя некоторые директивы angular/flex-layout:)