In the latest update of 2024: ::ng-deep remains a relevant topic, as it is not going away. However, the Angular team still suggests using it as a last resort.
It has been mentioned that when utilizing third-party libraries, occasionally using ::ng-deep
is almost unavoidable.
Lets explore some alternatives:
- Utilize ViewEncapsulation.None
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})
Note that breaking the component's encapsulation will result in the styles being globally accessible. To prevent conflicts and CSS issues, two approaches come to mind:
- Wrap your component's template with a class. For instance, example.component.html could look like this:
<section class="app-example-container">
<!-- a third party component -->
<mat-tab-group>
<mat-tab label="First"></mat-tab>
<mat-tab label="Second"></mat-tab>
</mat-tab-group>
</section>
With no Encapsulation, you can modify the third-party component by targeting their classes. Thus, example.component.scss would be:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
- Alternatively, use the component's tag name as a wrapper. For example:
app-example {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
- Employ Global styles
Add a new CSS file to your styles array in the angular.json
configuration file. However, note that maintaining global styles may become increasingly difficult over time. Personally, I recommend avoiding this option unless necessary :)
- Implement a directive
Although slightly cumbersome due to limited styling capabilities compared to components, directives can prove helpful at times. Alternatively, mimic how the Angular Material team applied styles with the buttons
- :host ::ng-deep
You are probably familiar with this method, but combining it with the host selector is advised by Angular for minimizing potential style clashes.
A reminder for future reference: https://angular.io/guide/component-styles
Official suggestions and alternatives can be found there
- Urge library developers to utilize CSS variables that can be customized from the parent component or through shadow parts (when feasible). The Ionic Team exemplifies this well. For further details, refer to here
Edit 1. As @beppe9000 pointed out in a comment, ::ng-deep is exclusive to Angular. Even if the feature is removed by the Angular team in the future, existing applications will continue to function. Previous confusion stemmed from the old /deep/
modifier.