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

by
Liam Thompson
angular angular-material-15 cssgrid html ng-deep

Quick Fix: In Angular Material 15, ::ng-deep is no longer supported. To target nested elements within components, utilize the Shadow DOM APIs. Define styles with unique class names in global styles or scss to avoid conflicts.

The Problem:

In Angular Material version 15, the ::ng-deep pseudo-class is deprecated. As a result, previously used styling for Material elements using ::ng-deep is no longer functional. How can you apply styling to Angular Material elements without using the deprecated ::ng-deep pseudo-class?

The Solutions:

Solution 1: Use Unique Class Names

Angular Material components are encapsulated, meaning that you can’t access the styles of elements inside them using regular CSS selectors. To style these elements, you can either use the ::ng-deep operator (deprecated) or you can define a unique class name and apply it to the component.

For example, to hide the select arrow in a mat-select component, you can add the following code to your HTML:

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

Then, you can add the following code to your CSS:

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

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

This will hide the select arrow in all mat-select components that have the no-arrow class.

Benefit:

  • Makes the component’s styles more specific and less likely to conflict with other styles.
  • Improves performance by reducing the amount of CSS that needs to be applied to the page.

Drawbacks:

  • Requires you to create a new class name for each style that you want to apply to an Angular Material component.
  • Can be difficult to maintain if you have a lot of Angular Material components in your application.

Solution 2: ::ng-deep Method

Using ::ng-deep is the preferred method of styling only material components inside a specific component. It allows for more targeted styling and is the most compatible with third-party packages.

To use ::ng-deep, add it to the selector of your CSS rule. For example:

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

This will hide the select arrow in all mat-select components within the host component.

It’s important to note that ::ng-deep should be used sparingly, and only for third-party packages. This is because it can make it difficult to migrate to a new styling system if one is introduced in the future.

Solution 4: Use ViewEncapsulation.None

To apply styles to Angular Material 15 elements, you can use the `ViewEncapsulation.None` option. This will allow you to style elements from your component’s template in the global CSS file.

To use `ViewEncapsulation.None`, add the following code to your component’s decorator:

“`
@Component({
selector: ‘app-my-component’,
templateUrl: ‘./my-component.html’,
styleUrls: [‘./my-component.css’],
encapsulation: ViewEncapsulation.None
})
“`

Once you have added `ViewEncapsulation.None`, you can add the following CSS rule to your global CSS file to hide the select arrow in a mat-select element:

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

This will hide the select arrow for all mat-select elements in your application.

Q&A

How to hide/remove select arrow in mat-select without using ::ng-deep?

Define the style in the global styles with a unique class name to avoid conflicts.

Why is ::ng-deep still not removed completely even though it’s deprecated?

There is no official replacement yet and it provides a way to style third-party packages.

How to access the styles of elements inside Angular Material components?

Use ::ng-deep sparingly, place styles in styles.css, or use ViewEncapsulation.None.

Video Explanation:

The following video, titled "Angular 15 Upgrade with NG Material - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

A video about an Upgrade from Angular 11 to Angular 15, with focus on ng material styles.