Search code examples
javascriptcssangularrouter-outletangular7

Angular 7 router-outlet sets height greater than window


I am working on an Angular 7 project which involves a single-page application with a toolbar across the top, a tab selector using routing, and a router-outlet. I am trying to get the total height of the application to 100% the viewport, fixed. The issue is that the content of router-outlet, when set to 100vh, expands itself to be 100% the viewport, causing it to go offscreen, or when set to 100%, doesn't show up at all. This is an issue identified here, but the proposed solution did not seem to work. Here is some relevant code:

app.component.html

<div class="fixed-location">
  <app-main-toolbar></app-main-toolbar>
  <nav mat-tab-nav-bar>
    <a mat-tab-link
       *ngFor="let link of navLinks"
       [routerLink]="['/'+link.path]"
       routerLinkActive
       #rla="routerLinkActive"
       [active]="rla.isActive ? true : null">
       {{link.label}}
    </a>
  </nav>
  <div class="filled" [@fadeAnimation]="o.isActivated ? o.activatedRoute : ''">
      <router-outlet #o="outlet"></router-outlet>
  </div>
</div>

app.component.css

.fixed-location {
  position: absolute;
  top: 0;
  width: 100vw;
  flex-direction: column;
  flex-flow: column;
  height: 100vh;
}

nav {
    text-align: center;
    align-items: center;
    justify-content: space-around;
    display: flex;
    flex-direction: row;
}

.filled {
    flex-grow: 1
}

designer-view.component.html (one item that populates router)

<mat-sidenav-container class="sidenav-container">
  <mat-sidenav class="sidebar-container" mode="side" opened>
      <app-elements-sidebar></app-elements-sidebar>
  </mat-sidenav>
  <mat-sidenav-content>
      <div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">
          <div class="example-box" *ngFor="let task of tasks" cdkDrag>{{timePeriod}}</div>
      </div>
  </mat-sidenav-content>
  <mat-sidenav mode="side" position="end" opened>
      <app-config-sidebar></app-config-sidebar>
  </mat-sidenav>
</mat-sidenav-container>

designer-view.component.css (one item that populates router)

mat-sidenav-container {
    display: flex;
    flex-direction: column;
    background-color: blue;
    height: 100%
}

.filled {
    flex-grow: 1;
    padding-top: 0px;
}


mat-sidenav {
    width: 250px;
    flex-grow: 1
}

Based on other questions and my own looking, it seems like the router doesn't actually contain the element, but rather the element is added below.

Is there an established way of making sure this doesn't overflow the window, or an angular-ish way of grabbing the item and setting the height?

Thanks!

EDIT: I added a stackblitz here


Solution

  • Your problem is solvable with css. you are setting mat-sidenav-container's height to 100vh that means to take all the window height. But if you add also a mat-toolbar and a nav element on top of your mat-sidenav-container you should set the height to 100vh - others component's height.

    So this is a solution:

    mat-sidenav-container[_ngcontent-c4] {
        display: flex;
        flex-direction: column;
        background-color: blue;
        /* height: 100vh; */
        height: calc(100vh - 64px - 49px);
    }