Char
Char

Reputation: 2133

Angular Material Select: How to customize .mat-select-panel itself

I have this structure of html using Angular Material Select

<mat-form-field class="year-drpdwn-vacay-stock">
    <mat-select placeholder="Year">
        <mat-option>None</mat-option>
        <mat-option *ngFor="let yr of year"  [value]="yr">{{yr}}</mat-option>
    </mat-select>
</mat-form-field>

I placed a class because I also use Select in other components. I tried adding

::ng-deep .mat-select-panel {
    margin-top: 20%; 
} 

in CSS to customize, but the problem is, other components containing another select box also gets affected (inherits the margin-top CSS)

Currently I have this CSS

.year-drpdwn-vacay-stock mat-select.mat-select :host ::ng-deep .mat-select-panel {
    margin-top: 20%; 
}

But it still doesn't work.

UPDATE

Goal: I want the options panel to move a bit downward upon opening the select box which is why I want .mat-select-panel to have a top margin of 20%

Upvotes: 18

Views: 47391

Answers (3)

Karthik Raja Ayyanar
Karthik Raja Ayyanar

Reputation: 21

To move a option panel bit downward upon opening the select box, use 'disableOptionCentering' attribute like below, which works for me.

<mat-select placeholder="Favorite food" disableOptionCentering>
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>

Upvotes: 2

Just code
Just code

Reputation: 13791

Use cdk-overlay-container as based and go to the options pane like this, mat-select uses absolute position without any child in it. so you need to apply your style to cdk-overlay-container

.cdk-overlay-container .cdk-overlay-pane{
   margin-top: 7%;
}

Here is the demo

Edit:

Ok so you have a conflict problem with other elements you can add

panelClass="testClass"

and

<mat-select placeholder="Favorite food" panelClass="testClass">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.viewValue}}
    </mat-option>
  </mat-select>

And change your class like this

.cdk-overlay-container .cdk-overlay-pane .testClass{
margin-top: 7%;
}

demo

Upvotes: 37

Akshay Rajput
Akshay Rajput

Reputation: 2078

  1. If you apply the style to class directly in styles.css (root) with, !important tag it will overwrite any other styles. But you will break encapsulation by doing it.
  2. If you apply styles in the component using /deep/ the style will be overwritten, mat-form-field /deep/ (class-name) {} (Deprecated issues) please read https://blog.angular-university.io/angular-host-context/ for an in-depth explanation
  3. Because of Deprecating issues, you can actually try to add/remove classes using vanilla javascript, but manipulating dom directly is a bad practice.

    Summary: Using Deprecated syntax is bad, applying style on root level will cause encapsulation issues, manipulating dom directly is a bad practice, so you can use the tools provided by angular to manipulate the dom to resolve above issues, please refer below link to learn about best practice to manipulate dom in angular https://blog.angularindepth.com/exploring-angular-dom-abstractions-80b3ebcfc02

Upvotes: 1

Related Questions