Search code examples
cssangularsassangular-materialng-deep

Unable to Apply CSS Styles to Angular Material mat-icon in Nested Components


I am trying to apply custom styles to a mat-icon element inside an Angular Material component, but no matter what I do, the styles won't take effect. Here's a simplified version of my code:

Html:

<mat-form-field appearance="fill" class="example-field">
  <mat-label>Select an Option</mat-label>
  <mat-select [formControl]="exampleControl" (selectionChange)="onOptionSelected($event.value)">
    <mat-option *ngFor="let option of availableOptions" [value]="option">
      <mat-icon [inline]="true">settings</mat-icon>
      {{ "example.option." + option | lowercase | translate }}
    </mat-option>
  </mat-select>
</mat-form-field>

CSS:

:host {
  ::ng-deep {
    mat-form-field {
      mat-select {
        mat-option {
          mat-icon {
            margin-right: 0;
          }
        }
      }
    }
  }
}

Solution

  • The select dropdown get's attached to the root element and not inside the component. To overcome this you can use panelClass to add a class to the dropdown root, and then style the inner contents.

    HTML:

    <h4>Basic mat-select</h4>
    <mat-form-field>
      <mat-label>Favorite Car</mat-label>
      <mat-select [panelClass]="'custom-dropdown'">
        @for (car of cars; track car) {
    
        <mat-option [value]="car" [appTransform]="car">
          <mat-icon [inline]="true">settings</mat-icon>
        </mat-option>
        }
      </mat-select>
    </mat-form-field>
    

    From Global styles:

    .custom-dropdown {
      mat-option.mat-mdc-option {
        mat-icon.mat-icon,
        mat-icon.mat-pseudo-checkbox-full {
          margin-right: 0;
        }
      }
    }
    

    Stackblitz Demo


    From Component:

    ::ng-deep .custom-dropdown {
      mat-option.mat-mdc-option {
        mat-icon.mat-icon,
        mat-icon.mat-pseudo-checkbox-full {
          margin-right: 0;
        }
      }
    }
    

    Stackblitz Demo