DEV Community

Cover image for ng-deep is no longer needed
Maksim Dolgih
Maksim Dolgih

Posted on • Updated on • Originally published at Medium

ng-deep is no longer needed

External library component

Let’s imagine that we are developing an Angular library of UI components for the rest of the teams.

We have a simple component that displays a header and a description

    @Component({
     selector: 'lib-external-component',
     standalone: true,
     imports: [],
     template: `
       <h2 class="header">{{header}}</h2>
       <span class="description">{{description}}</span>
     `,
     styleUrl: './external-component.component.scss'
    })
    export class ExternalComponentComponent {
     @Input()
     public header = 'External component header'


     @Input()
     public description = 'External component description'
    }
Enter fullscreen mode Exit fullscreen mode
    :host {
     display: block;
     padding: 8px 12px;
     outline: 1px solid #b7b7b7;


     .header {
       font-size: 18px;
       font-weight: bold;
       color: red;
     }


     .description {
       font-size: 14px;
       color: blue;
     }
    }
Enter fullscreen mode Exit fullscreen mode

Сomponent visualization

Currently, when we change the theme, the component does not pick up our styles and remains unchanged

Switching themes does not affect the component

How can we style .header and .description?

There are three options:

  • Customize globally via a generic styles.scss file

  • Customize the style of the component in the parent component style with ViewEncapsulation.None

  • Customize the style of the component in the parent component by wrapping that in ::ng-deep

The first two options may be used depending on the situation and if they do not break the overall styling logic.

But ng-deep is a deprecated selector, and developers continue to use it as a “magic pill” for accessing styles of a child component.

Overriding styles in a parent component with theme support may look like this

    @each $theme-key in map.keys(variables.$themes) {
     $theme: map.get(variables.$themes, $theme-key);


     :host-context([data-theme="#{$theme-key}"]){
       ::ng-deep {
         app-external-component {
           .header {
             color: map.get($theme, "primary");
           }


           .description {
             color: map.get($theme, "secondary");
           }
         }
       }
     }
    }
Enter fullscreen mode Exit fullscreen mode

Let’s check the support of our themes for the external component

Switching themes affects the component via ng-deep

We got the result we wanted but created a lot of complex code to style the component, which inherited all the styling issues for generic styling

Is it possible to simplify all this and even get rid of using ::ng-deep? read more...

Top comments (0)