How to replace ::ng-deep in Angular Material 15

3.1k views Asked by At

How to apply style for Angular Material 15 elements? Nothing except ::ng-deep is working for me. According to official docs https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep ::ng-deep is deprecated so I want to avoid using it.

E.g. I want to hide/remove select arrow in mat-select. I have a code like this and it doesn't work without ::ng-deep. I also tried to write the code from the root, css variables but it also didn't work.

HTML

<div class="div-test">
  <mat-select [(value)]="selected.id">
    <mat-option value="en"></mat-option>
    <mat-option value="nl"></mat-option>
  </mat-select>
</div>

CSS

.mat-mdc-select-arrow  {
 display: none;
}

How does it look: enter image description here

4

There are 4 answers

0
Domske On BEST ANSWER

Yes, using ::ng-deep or similar is never a good idea. In your case you could either check if the framework supports this per API, find alternatives or define this style in the global styles with unique class name to avoid conflicts. For example:

your-component.html

<mat-select class="no-arrow">
  ...
</mat-select>

styles.css (or scss or project defined. global styles)

mat-select.no-arrow .mat-mdc-select-arrow-wrapper {
  display: none;
}

/* or on native select (matNativeControl) */
select.no-arrow::after {
  display: none;
}

You could also make your class name more unique like select-no-arrow. By default, you cannot access the styles of elements inside Angular Material components, because they are encapsulated.

1
AhmedSHA256 On

Styling material components can be really tricky sometimes. What we use at our company is adding encapsulation in the component, like this:

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

This should help, but if it even doesn't work, just use ::ng-deep

0
Askirkela On

When defining style rules in a component, only this component's instances will apply the rules (as per view encapsulation).

So if you put your CSS rule in the root "styles.css", the redefinition of rules (like for material) should apply (you can event add a selector like .i-want-that.mat-mdc-select-arrow so you can always have the material component like it was designed).

0
Jineapple On

Yes, ::ng-deep has been deprecated, but that has been the case since at least Angular 6 (https://v6.angular.io/guide/component-styles) and it has not been removed yet.

The reason for that is that there is not yet a sufficiently useful w3c standard to replace it. There are some efforts, but nothing that would work for existing third party packages who don't offer explicit support for external styling.

The only way to so in Angular is by going around view encapsulation in some way, either placing styles directly in styles.css, using ViewEncapsulation.None, or using ::ng-deep.

Of those, :host ::ng-deep is still the preferrable method if you want to style only material components inside a specific component of yours. Otherwise you can use the global styles.css.

You should still use this sparingly if possible, and only for third party packages, to make migration easier if a working alternative is introduced at some point and ::ng-deep disabled. However, this does not seem likely to happen soon.