Best way to manage height of angular components to fit in screen

I am having troubles with height of my components... I have a mat-toolbar in a component called app-navbar, and I have another component called app-sidebarwith a mat-nav-list (which is a side left bar menu)

I have a third component which gets both together, but this is happening:

enter image description here

Last item of the nav-list I want it at the bottom of the page, but giving 100% height to mat-sidenav-container component, makes it go "out" of the page, even if the content of the page has no scroll. I can have it correctly by setting it's height as: height: calc(100% - 64px) which 64px is height of th material toolbar (by default). I don't feel like this is a correct solution, because if material decides sometime on changing the size of the height, I will have troubles.

Is there any way using flex or similar to make it better?

HTML:

<div>
  <app-navbar [mySideBar]="snav" fxFlex></app-navbar>
</div>
  <mat-sidenav-container>
    <mat-sidenav autoFocus="false"
                  #snav mode="side"
                  fixedInViewPort="true"
                  [mode]="side"
                  [opened]="true">
      <app-sidebar [mySideBar]="snav"></app-sidebar>
    </mat-sidenav>
    <mat-sidenav-content fxLayout="column">
      <!-- content -->
    </mat-sidenav-content>
  </mat-sidenav-container>

CSS:

mat-sidenav-container {
  height: calc(100% - 64px);
}

Or maybe reading height size of mat-toolbar instead of hardcoding it?

2 answers

  • answered 2019-10-15 17:19 Henrique Erzinger

    No, I would say the calc method is the best one. That's how I do the same thing, at the very least. You can protect yourself from random material design changes somewhat by setting yourself the toolbar height. If you're using SASS, you can store the toolbar height in a variable (or a map, with the height for each media-query, if it changes), and use it both for the height in the toolbar and for the calc with height: calc(100vh - #{$toolbar-height}).


    Edit:

    Just for fun, I did a quick and dirty model with css grid. It works okay, but I'm not sure how much of it would be viable for your particular code, so the answer still stands anyway. Just an option to consider:

    body { margin: 0; padding: 0; }
    
    .main {
      display: grid;
      grid-template-rows: 64px 1fr;
      grid-template-columns: 300px 1fr;
      height: 100vh;
    }
    
    .toolbar {
      background:  grey;
      width:       100%;
      grid-column: span 2;
    }
    
    .sidebar {
      background: #BAD;
    }
    
    .content {
      padding: 24px;
      overflow: auto;
    }
    <div class="main">
      <div class="toolbar"></div>
      
      <div class="sidebar"></div>
      
      <div class="content">
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Quia dolores odio consequuntur beatae? Doloribus corrupti accusantium dolore, fuga magni eaque odio perferendis autem voluptatem distinctio alias ducimus consequatur debitis dignissimos.</p>
        
      </div>
    </div>

  • answered 2019-10-16 09:04 Esteban Chornet

    I could finally make it after trying some time with fxFlex.

    Parent component (which gets both together):

    height: 100%
    display: flex;
    

    And put both components inside of a <div fxLayout="column" fxFlex=100%> <!--components--> </div>

    For <app-navbar> remove the fxFlex and give component width: 100%

    For <app-sidebar>this CSS:

    :host {
      overflow: hidden;
      display: flex;
      -webkit-flex: 1;
      -ms-flex: 1;
      -o-flex: 1;
      flex: 1;
      flex-direction: column;
    }
    

    And for <mat-sidenav-container> give fxFlex="100%"