Search code examples
cssangularencapsulationng-deep

What is the the scope of ::ng-deep?


A lot of our site is structured as such:

  • component
    • component CSS
    • component template
      • child component

We often need to style the child component differently based on which parent component it was in. This is annoying, of course, but was manageable when we were using global CSS as we could simply target the specific instance with unique ID and class CSS selectors.

We're trying to now stop using global styles and encapsulating our CSS within each component. The problem with this is that, from what I see, encapsulate angular CSS will scope your CSS so that it only applies to that component...which means it also will not apply to any child components.

One solution appears to be to use ::ng-deep selectors in our component CSS to target the child. This is meeting some resistance, though, as I'm being told this also breaks encapsulation in general and could affect other parts of the site in different components.

This is where I'm confused. Some questions:

Does any style targeted with ::ng-deep become descoped so that it is global application-wide? Or is it simply 'global' within that one parent component?

If it's the former, would it be an OK practice to still use ::ng-deep, but also make sure you are using additional unique css selectors so it only applies to the child component you are targeting?

Or is there a more proper way to add styles to a particular child component instance?


Solution

  • :ng-deep is global. No matter where you put it, it applies to all components. Not just children.

    If you use :host :ng-deep, then it will work from that component down (Into the children, grand children etc).

    The main issue working with ng-deep is that styles in Angular are lazy loaded. So in some cases, you can be viewing the site perfectly fine, then you view a particular page that uses ng-deep, then you can go back to previous pages that were fine that are now broken because the ng-deep style is applied site wide. e.x. https://tutorialsforangular.com/2020/04/13/the-dangers-of-ng-deep-bleeding/

    Generally speaking, if I need to style a child component slightly differently depending on where it's placed, then I create an input variable for the child, make the parent set it, then make it a class somewhere in the child component HTML. The child component can then style that class how it see's fit and you haven't had to break encapsulation.