In angular7, how do I change the height of a mat-select when shows the list of items?

39,931

Solution 1

Like this helpful answer to a similar question already states there are a couple of ways you can solve this problem and which one you choose depends on whether you want to apply your rules globally or locally. None of the following examples require you to change the ViewEncapsulation type of your component.

Local override

Using ::ng-deep you can simply override the styles of both the trigger and the panel that are being rendered in child components of your component. Important: ::ng-deep has been marked as deprecated and while it still works there is no guarantee it will do so in future.

select-multiple-example.component.css

::ng-deep .mat-select-trigger {
  min-width: 80vw;
}

::ng-deep .mat-select-panel {
  max-height: 80vh !important;
}

select-multiple-example.component.html

<mat-form-field>
  <mat-select placeholder="ITEMS" multiple>
    <mat-option *ngFor="let item of items" [value]="topping">{{item}}</mat-option>
  </mat-select>
</mat-form-field>

DEMO (I edited your code for the purpose of the demo)


Global override

This will apply your overrides to all triggers or panels within your application.

styles.css

.mat-select-trigger {
  min-width: 80vw;
}

.mat-select-panel {
  max-height: 80vh !important;
}

DEMO (overrides can be found in /assets/styles/material-override.scss)


Flexible override

Using the @Input pannelClass on your MatSelect (mat-select) will allow you to apply different overrides depending on your use case and independent from other selects in your app.

styles.css

.panel-override {
  max-height: 80vh !important;
}

.panel-override-2 {
  max-height: 100px !important;
}

select-multiple-example.component.html

<mat-form-field>
  <mat-select placeholder="ITEMS" multiple [panelClass]="applyPanelOverride2 ? 'panel-override-2' : 'panel-override'">
    <mat-option *ngFor="let item of items" [value]="item">{{item}}</mat-option>
  </mat-select>
</mat-form-field>

DEMO (note the checkbox in the toolbar)

Solution 2

Re the update, try to use max height instead of min.

If you use Gordans suggestion of @Input Panelclass, use 'panelClass=..." instead of '[panelClass]=...', otherwise the styling won't take affect.

Share:
39,931

Related videos on Youtube

Woody
Author by

Woody

Updated on July 09, 2022

Comments

  • Woody
    Woody almost 2 years

    In Angular7, how can I increase the height of a mat-select when it is showing the items? I have the following component file:

    import { Component, ViewEncapsulation } from "@angular/core";
    import { FormControl } from "@angular/forms";
    
    /** @title Select with multiple selection */
    @Component({
      selector: "select-multiple-example",
      templateUrl: "select-multiple-example.html",
      styleUrls: ["select-multiple-example.css"],
      encapsulation: ViewEncapsulation.None
    })
    export class SelectMultipleExample {
      toppings = new FormControl();
      toppingList: string[] = [
        "Extra cheese",
        "Mushroom",
        "Onion",
        "Pepperoni",
        "Sausage",
        "Tomato",
        "CBFnTQcZ79AeYrdq",
        "1KiYwRjeqdqjNzVb",
        "TeLvgGl7t3yHDrZE",
        "s3ivzgLZO9qDNovJ",
        "QOOH2MCNRRXVJNwD",
        "1RWqdyPpu8yHSDoO",
        "d3aAOYIWYJE695Lf",
        "JoXDWP6zKSrZTIUc",
        "hpxQKFJsJcgVey5A",
        "UMI0akuHn2M5BaAP",
        "LRnQgNNjpqZwpdzj",
        "ZDIgw68mQyNLtxob",
        "Q6HY6tcqFcySJqD9",
        "WVFSg4TKeEqqoF1g",
        "ka4ORT9rUW8EPaPd",
        "ingfHsjBXAmt7yvo",
        "G3MY6MowhI7s0fN9",
        "ZlWqSoRnlhXQCbYz",
        "gerR70hrO5alwsOR",
        "dk0xrarQzfH6HAdl",
        "D1WCkB9jhhPMiuv7",
        "zPMj4g6Iu52jXqwq",
        "P4OEXKI2FZfFVqVn",
        "xMcOFx5m92d9oGQz",
        "dkyWq0tLJ8wQknaA",
        "iJZUeyjyyn3qQaCT",
        "5KhUjwEJK8wIYkoa",
        "YB3rEUkE12Pf9hcO",
        "qzrzSvzDXukVXvZi",
        "Hr1lccIcJZurLKiL",
        "noQo0pUMBeuQGpcf",
        "Tw4ACNCyDbpMI5MQ",
        "kK3QMSqyrNAwo3J0",
        "lvXP7qEm3biOpVbu",
        "gzy7bHaW2Qq6StN0",
        "GjXJAaRovr5CwHaO",
        "7CfVdILE7RhaVDvI",
        "8i5j8nlokIdkPEoO",
        "XpSWhgdwON3XFI15",
        "w5R5JfrDnuCzhqN7",
        "azhjvfD5geZaKjfc",
        "6y1Zdt18KSRNMdxx",
        "kd5ou8n6Ae5sILpj",
        "2p0YQKWdOvpXo4cD",
        "XfmEOsiIpq4C0PVc",
        "qYIzI8y3vOdx2KJ6",
        "6MzPKWHOn1oFOHpd",
        "tJgyk3p4UIDEj985",
        "RXwLNofzoJHUYgOf"
      ];
    }
    

    Where I am able to set the width with the following CSS and html:

    CSS:

     .myFilter .mat-select-trigger {
      min-width: 80vw;
    }
    

    HTML:

    <mat-form-field>
      <mat-select class="myFilter" placeholder="Pizza Stuff" [formControl]="toppings" multiple>
        <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
      </mat-select>
    </mat-form-field>
    

    Which is fine, but I want to be able to set the height not the width. If I try and change the CSS to this:

    .myFilter .mat-select-trigger {
      max-height: 80vh;
    }
    

    then the height of the box increases and not the actual list of items. Assuming that I am somehow able to do that, how can I then ensure that the list doesn't extend beyond the number of items in the toppingList array if, for example, the data contained within it is updated to

    toppingList: string[] = [
        "Extra cheese",
        "Mushroom",
        "Onion",
        "Pepperoni",
        "Sausage",
        "Tomato",
        "CBFnTQcZ79AeYrdq",
        "1KiYwRjeqdqjNzVb",
        "TeLvgGl7t3yHDrZE",
        "s3ivzgLZO9qDNovJ",
        "QOOH2MCNRRXVJNwD",
        "1RWqdyPpu8yHSDoO",
        "d3aAOYIWYJE695Lf",
        "JoXDWP6zKSrZTIUc",
        "hpxQKFJsJcgVey5A"
      ];
    

    In other words, if the list is reduced, how can I show all items and remove the scrollbar? Thanks in advance.

    UPDATE:

    So I have made the following changes: CSS:

    .myFilter {
      background-color: yellow; /* Added this to check it was working*/
      min-height: 85vh;
    }
    

    HTML:

    <mat-form-field>
      <mat-select [panelClass]="'myFilter'" placeholder="Pizza Stuff" [formControl]="toppings" multiple>
        <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping}}</mat-option>
      </mat-select>
    </mat-form-field>
    

    Which has changed the height to 85vh but if I have only 5 items I want the list shorter.

  • aruno
    aruno over 4 years
    Your 'component' version doesn't really work. Well it does, but only because of a wrong assumption. First ::ng-deep .mat-select-panel in a component actually DOES define this css for the global space. So as soon as your component is used the first time this css is now in the global scope and stays there forever. So if you have one component that uses this it will break the second component. So your 'flexible override' is by far the best way to go. The css MUST be in the global scope because mat-select uses an overlay so component css wouldn't take effect on the actual dialog.
  • Raphaël Balet
    Raphaël Balet over 3 years
    Changing the default max-height may move some part off the screen and could make some option not selectable (These chances are bigger if you're using it within a MatDialog)