Components: <mat-grid-list> rowHeight="fit" crashes page

Created on 13 Mar 2018  路  15Comments  路  Source: angular/components

Bug, feature request, or proposal:

BUG

What is the expected behavior?

I would expect when using rowHeight="fit" for the rowHeight to dynamically change depending on the contents of mat-grid-tile(s)

What is the current behavior?

mat-grid-list crashes

What are the steps to reproduce?

This stackblitz shows the working code, without using rowHeight but as you can see the mat-list is not rendering correctly.

https://stackblitz.com/edit/angular-cccnjp?file=app%2Fsidenav-responsive-example.html

Then if I use the same code and add rowHeight="fit" nothing renders (although the html is generated, if I inspect the element with dev tools)

https://stackblitz.com/edit/angular-cccnjp-ylmzf9?file=app/sidenav-responsive-example.html

What is the use-case or motivation for changing an existing behavior?

N/A

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Currently using Angular5.2.6, Material 5.2.1, Linux & Windows tests TS 2.7.1, Firefox and Chrome tested

Is there anything else we should know?

N/A

Most helpful comment

If you have to set an exact height, how can I create a responsive page? Surely mine cannot be the only use case where you want the container/div/element to scale to the size of the content?

All 15 comments

From the docs:

Fit: Setting rowHeight to fit This mode automatically divides the available height by the number of rows. Please note the height of the grid-list or its container must be set.

This still does not work, example:

<mat-grid-list cols="2"  class="myGridList" rowHeight="fit">
.myGridList {
    height: 100%;
}

Example https://stackblitz.com/edit/angular-cccnjp-zcfj4w?file=app/sidenav-responsive-example.html

You have to set an exact height.

If you have to set an exact height, how can I create a responsive page? Surely mine cannot be the only use case where you want the container/div/element to scale to the size of the content?

You might be able to stretch it using something like flexbox.

So to get the above combination working correctly, I have had a bit of a hacky solution, see:

https://stackoverflow.com/questions/49234018/angular-material-mat-grid-list-not-expanding?noredirect=1#comment85535332_49234018

@crooksey from Brian's great blog post on using Flex Layout to create a responsive mat-grid-list, you can use Angular Flex Layout's ObservableMedia service and set the rowHeight in the mat-grid-list dynamically as the number of columns change.

example:

<mat-grid-list [cols]="cols | async" gutterSize="16px" [rowHeight]="rowHeight + 'px'">
...
</mat-grid-list>
ngOnInit() {
    const grid = new Map([
      ['xs', 1],
      ['sm', 2],
      ['md', 4],
      ['lg', 4],
      ['xl', 4]
    ]);

    let start: number;

    grid.forEach((cols, mqAlias) => {
      if (this.observableMedia.isActive(mqAlias)) {
        start = cols;
      }
    });

    // on breakpoint, assign cols AND ROW HEIGHT appropriately
    this.cols = this.observableMedia.asObservable()
      .map(change => {

        this.rowHeight = this.heightToCols(grid.get(change.mqAlias));
        console.log(this.rowHeight);

        return grid.get(change.mqAlias);

      })
      .startWith(start);
  }

  heightToCols(cols: number): number {
    if (cols === 1) {
      return 250;
    } else if (cols === 2) {
      return 300;
    } else {
      return 350;
    }
  }

Use Angular flex layout, it will solve all geometry issues.

so this bug is not going to be solved?

@aWeinzierl you need to use angular material with flexbox to get the desired functionality I was initially after.

Yeah, but should not rowHeight="fit" do the job, too - despite not using absolute values?

Thanks for the flexbox clue, but I just abandoned mat-grid and went with plain css-grid, which is doing an excellent job at providing an easy and concise solution. (at least so far - I am not extremely experienced)

Angular material says on Grid List Documentation:

Fit: Setting rowHeight to fit This mode automatically divides the available height by the number of rows. Please note the height of the grid-list or its container must be set.

So basically in here:
https://stackblitz.com/edit/angular-cccnjp-ylmzf9?file=app/sidenav-responsive-example.html

_Instead of_ <mat-grid-list cols="2" rowHeight="fit">
something like <mat-grid-list cols="2" rowHeight="fit" style="height: 400px">
And it works perfectly

Regrettably, Angular has the worst Google material implementation (in comparison to VueJS/Vuetify or React/MaterialUI) because nothing works really properly. Every solution above does not work as expected. The only way out is: https://github.com/angular/flex-layout

this problem can be solved using flexbox.

.container {
  display: flex;
  flex-wrap: wrap;
}

.item {
  flex-grow: 1;
  flex-basis: 300px;
  margin: 10px;
}
<div class="item">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
  <div class="item">D</div>  
  <div class="item"></div>   
  <div class="item"></div>  
</div>

you can find more details here :
https://www.vinta.com.br/blog/2017/responsive-layout-flexbox/

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RoxKilly picture RoxKilly  路  3Comments

vanor89 picture vanor89  路  3Comments

michaelb-01 picture michaelb-01  路  3Comments

theunreal picture theunreal  路  3Comments

constantinlucian picture constantinlucian  路  3Comments