Styling mat-select in Angular Material

CssAngularTypescriptAngular Material

Css Problem Overview


How to style mat-select's panel component. From the docs I get that I need to provide panelClass so I make it like this:

<mat-form-field>
  <mat-select placeholder="Search for"
    [(ngModel)]="searchClassVal"
    panelClass="my-select-panel-class"
    (change)="onSearchClassSelect($event)">
    <mat-option *ngFor="let class of searchClasses" [value]="class.value">{{class.name}}</mat-option>
  </mat-select>
</mat-form-field>

I inspected in developer tools that this class is attached to the panel in DOM and it is attached. So I have my custom scss class attached to this element. Now when I provide css it just don't work. My scss for example looks like this:

.my-select-panel-class {
    width:20px;
    max-width:20px;
    background-color: red;
    font-size: 10px;
}

The width of the panel is always equal to the width of the select element. Sometimes In options You have too long strings and I would like to make it a little bit wider. Is there any way how to do this. My style from my component just not working even background-color is not working. Does somebody knows why this behaves so strange?

I'm using: Angular 4.4.5 @angular/material: 2.0.0-beta.12

Css Solutions


Solution 1 - Css

For Angular9+, according to this, you can use:

.mat-select-panel {
    background: red;
    ....
}

Demo


Angular Material uses mat-select-content as class name for the select list content. For its styling I would suggest four options.

1. Use ::ng-deep:

> Use the /deep/ shadow-piercing descendant combinator to force a style > down through the child component tree into all the child component > views. The /deep/ combinator works to any depth of nested components, > and it applies to both the view children and content children of the > component. > Use /deep/, >>> and ::ng-deep only with emulated view encapsulation. > Emulated is the default and most commonly used view encapsulation. For > more information, see the Controlling view encapsulation section. The > shadow-piercing descendant combinator is deprecated and support is > being removed from major browsers and tools. As such we plan to drop > support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until > then ::ng-deep should be preferred for a broader compatibility with > the tools.

CSS:

::ng-deep .mat-select-content{
    width:2000px;
    background-color: red;
    font-size: 10px;   
}

DEMO


2. Use ViewEncapsulation

> ... component CSS styles are encapsulated into the component's view and > don't affect the rest of the application. > To control how this encapsulation happens on a per component basis, > you can set the view encapsulation mode in the component metadata. > Choose from the following modes: >.... > None means that Angular does no view encapsulation. Angular adds the > CSS to the global styles. The scoping rules, isolations, and > protections discussed earlier don't apply. This is essentially the > same as pasting the component's styles into the HTML.

None value is what you will need to break the encapsulation and set material style from your component. So can set on the component's selector:

Typscript:

  import {ViewEncapsulation } from '@angular/core';
  ....
  @Component({
        ....
        encapsulation: ViewEncapsulation.None
 })  

CSS

.mat-select-content{
    width:2000px;
    background-color: red;
    font-size: 10px;
}

DEMO


3. Set class style in style.css

This time you have to 'force' styles with !important too.

style.css

 .mat-select-content{
   width:2000px !important;
   background-color: red !important;
   font-size: 10px !important;
 } 

DEMO


4. Use inline style

<mat-option style="width:2000px; background-color: red; font-size: 10px;" ...>

DEMO

Solution 2 - Css

Put your class name on the mat-form-field element. This works for all inputs.

Solution 3 - Css

Working solution is by using in-build: panelClass attribute and set styles in global style.css (with !important):

https://material.angular.io/components/select/api

/* style.css */
.matRole .mat-option-text {
  height: 4em !important;
}

...

Solution 4 - Css

In css copy this code to make 100% width

mat-form-field {
  width: 100%;
}

Solution 5 - Css

Angular material 11.2.6

      <mat-select class="text-sm">
        <mat-option> Text </mat-option>
      </mat-select>

Where text-sm (as of tailwind)

.text-sm {font-size: 0.75rem}

Solution 6 - Css

Here's a fully fledged solution for styling mat select.

HTML follows:

<mat-form-field class="booking-facility">
  <mat-select disableOptionCentering placeholder="facility" panelClass="booking-facility-select" [ngModel]="facilityId"
                      (ngModelChange)="updateFacility($event)">
    <mat-option *ngFor="let fac of facilities | keyvalue" [value]="fac.value.id">
      <span>{{ fac.value.name | lowercase }}</span>
    </mat-option>
  </mat-select>
</mat-form-field>

SCSS follows (use global stylesheet, namely styles.scss):

.booking-facility-styles {
  font-family: "Nunito Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  letter-spacing: 1px;
  font-size: 22px;
  color: #55595C;
}

.booking-facility {
  // label
  @extend .booking-facility-styles;

  // label
  .mat-form-field-label {
    @extend .booking-facility-styles;
    color: #BBB !important;
  }

  .mat-select-value-text {
    // select
    @extend .booking-facility-styles;
  }
}

.booking-facility-select .mat-option {
  // options
  @extend .booking-facility-styles;
  font-size: 16px !important;
}

Solution 7 - Css

  .mat-form-field .mat-input-element, .mat-form-field .mat-select,
  .mat-form-field.mat-form-field-appearance-legacy .mat-input-element,
  .mat-form-field.mat-form-field-appearance-legacy .mat-select {
    background-color: #0A0A0A !important;

    .mat-select-value {
      color: #fefefe !important;
      font-size: 14px !important;
      font-weight: $font-w-light;
    }
  }

Solution 8 - Css

In your component, disable styles encapsulation:

@Component({
    selector: 'xxx',
    templateUrl: './xxx.component.html',
    styleUrls: ['./xxx.component.scss'],
    encapsulation: ViewEncapsulation.None
})

For appearance (color/font), use

.mat-select-panel {
   background: red;
}

Having options with very long text, you may want to change width of the list. In such case you should use:

.mat-form-field {
    width: 100%;

    .mat-form-field-infix {
        width: 100%;
    }
}

No !important; css shenanigans required.
(tested with ang12+)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarcin KapustaView Question on Stackoverflow
Solution 1 - CssVegaView Answer on Stackoverflow
Solution 2 - CssLee GrindonView Answer on Stackoverflow
Solution 3 - CssAleksandr SkobeltcynView Answer on Stackoverflow
Solution 4 - CssKevin JoseView Answer on Stackoverflow
Solution 5 - CssCristian CimucaView Answer on Stackoverflow
Solution 6 - Cssdanday74View Answer on Stackoverflow
Solution 7 - CssJavid GahramanovView Answer on Stackoverflow
Solution 8 - Cssadrian.krzysztofekView Answer on Stackoverflow