22

I am trying to have a full page Angular Material tab which has tabs which are full height and have a centered message. I have created this stakblitz as I can't get it to work. The fxFill's don't seem to Fill and I am not sure if this is an issue with the Flexbox layout or Angular Material. I don't want to force a height as within each tab as that seems to defeat the point of flexible layouts.

Am sure its simple but help a poor confused developer who is used to Bootstrap grid :)

UPDATE Adding height: calc(100vh - 100px); to the parent div and then also to the tall.component div makes things work but surely this is a bad solution

Mad Eddie
  • 943
  • 3
  • 12
  • 23
  • One reason it can be a bad solution is that `vh` is pretty much a fixed value on mobile devices with or without the onscreen keyboard, or toolbars which appear and disappear differently across platforms. Be cautious of this and that if you expect `vh` to be truly dynamic it may not be. % actually often works better here. – Simon_Weaver Feb 18 '19 at 06:32

3 Answers3

31

In order to fill the page, the page needs to fill the window:

styles.css

body, html{
  height: 100%;
  margin: 0;
}

The app component needs to fill the body:

app.component.css

:host{
  box-sizing: border-box;
  display: block;
  height: 100%;
}

By default the wrappers of the content within the tabs are not filling the tab's height so we will fix this:

styles.css

.mat-tab-body-wrapper{
  flex-grow: 1;
}

We also need to have the mat-tab-group fill the height, its parent needs to fill the height too, so we will give an id to both the wrapper and the tab-group.

app.component.html

<div id="wrapper"> <!-- give it an id -->
    <div fxLayout="row" fxLayoutGap="16px" fxFill>
        <div fxFlex="20">
            <p>Fun Sidebar</p>
        </div>
        <div fxFlex="80" fxFill>
            <mat-tab-group id="tab-group"> <!-- give it an id -->
                <mat-tab label="Summary">
                    <div fxFlex style="padding: 16px;">
                        <div class="mat-display-2">Hello</div>
                        <p>Lorem ipsulem</p>
                    </div>
                </mat-tab>
                <mat-tab label="Tall content">
                    <app-tall-component></app-tall-component>
                </mat-tab>
            </mat-tab-group>
        </div>
    </div>
</div>

app.component.css

#wrapper{
  padding: 16px; 
  min-height: 100%; 
  height: 100%; 
  box-sizing: border-box;/*new*/
}
#tab-group{
  height: 100%;
}
#tab-group mat-tab-body {
  flex-grow: 1;
}

https://stackblitz.com/edit/angular-awamwn?file=src%2Fapp%2Fapp.component.html

j3ff
  • 5,719
  • 8
  • 38
  • 51
Ploppy
  • 14,810
  • 6
  • 41
  • 58
  • Thanks - Works perfectly - Although when I translate to my code the mat-tab-body-wrapper does not have the style : flex-grow: 1 which is being automatically applied in our code. Odd - Without it - your code doesn't work. – Mad Eddie Jun 06 '18 at 14:59
  • 3
    Thanks! Read again :) there is a section about it, you have to add it a rule to set it to flex in your styles.scss – Ploppy Jun 06 '18 at 15:01
  • 1
    Sorry missed that as I added it to the component scss instead :P – Mad Eddie Jun 07 '18 at 06:37
  • 1
    there is a native solution by setting dynamicHeight input to true – Suhayb Apr 11 '19 at 20:33
  • If not using fxLayout, can we implement with pure css flex? – Bigeyes May 23 '21 at 23:49
13

This is worked for me to assign dynamic value for height.

:host ::ng-deep .mat-tab-body-wrapper {
  height: 600px;

}

:host ::ng-deep .mat-tab-body.mat-tab-body-active {
  height: 600px;

}
AHL
  • 493
  • 5
  • 8
8

According to Angular docs: you need to set the dynamicHeight input to true <mat-tab-group dynamicHeight>

By default, the tab group will not change its height to the height of the currently active tab. To change this, set the dynamicHeight input to true. The tab body will animate its height according to the height of the active tab.

Raphaël Balet
  • 6,334
  • 6
  • 41
  • 78
Suhayb
  • 3,163
  • 3
  • 23
  • 30