As someone stated before, if you're using a third party library it's virtually impossible to avoid the ::ng-deep
once in a while.
Let's have a look to some alternatives
- Use ViewEncapsulation.None
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})
Be aware that breaking the encapsulation of the component will make the styles globally available. I can think in 2 ways to avoid collisions and CSS weirdness:
- Wrap your component's template with a class. So, example.component.html should be like:
<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>
Now, since there's no Encapsulation you can modify the third party component by targeting their classes. That said, example.component.scss should be like:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
- or use the component's tag name as wrapper. For example:
app-example {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
- Use Global styles
As simple as adding a new CSS file to your styles array of your angular.json
configuration file. Be aware that this will eventually become harder and harder to maintain. Personally, I'd avoid this option or use it as a last resort :)
- Use a directive
I will agree that it's a bit painful because you can't include Styles in a directive (in the same way you can do it in a Component), but it can be handy sometimes. You could also use a component to apply the styles the same way the Angular Material team did with the buttons
- :host ::ng-deep
You already know about this one, just wanted to make clear that using it together with the host selector is the Angular recommended way to avoid potential styles collisions.
A self note to the future: https://angular.io/guide/component-styles
That should be the first place to look at for official alternatives/ways-to-go
- Encourage library authors to use CSS variables that you could customize from the parent component or shadow parts (when possible). The Ionic Team did a great job at these. For a more detailed explanation you can check here
Edit 1. As @beppe9000 mentioned in a comment, ::ng-deep is an Angular thing. Even if the Angular team remove this feature tomorrow, your already deployed app will continue working. The confusion arose because of the old /deep/
modifier.