2

I'm trying to access and edit the CSS class of a child component using ::ng-deep. I have tried different versions of the provided code below but I was unable to access the CSS. The structure of the HTML component is as follows:

enter image description here

This is how I'm trying to access the CSS from the parent component and change the grid-template-columns property of the class:

::ng-deep{
  app-operator-filter{
    .header-logos-card{
      grid-template-columns: repeat(4,1fr);
    }
  }
}

What is the correct syntax for achieving this? I'm also open to other suggestions for accessing child components as I've read that ::ng-deep is not reliable and could be deprecated soon?

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
Vasko Vasilev
  • 554
  • 1
  • 10
  • 25

7 Answers7

4

Using ::ng-deep pseudo-class to any CSS rule will completely breaks the view-encapsulation for that rule and it becomes a global style. So, try to use it with :host as Angular official Doc suggests.

Applying the ::ng-deep pseudo-class to any CSS rule completely disables view-encapsulation for that rule. Any style with ::ng-deep applied becomes a global style. In order to scope the specified style to the current component and all its descendants, be sure to include the :host selector before ::ng-deep. If the ::ng-deep combinator is used without the :host pseudo-class selector, the style can bleed into other components.

So, try something like this:

:host ::ng-deep app-operator-filter {
  .header-logos-card {
    grid-template-columns: repeat(4,1fr);
  }
}
ng-hobby
  • 2,077
  • 2
  • 13
  • 26
2

It should work

::ng-deep .header-logos-card {
  grid-template-columns: repeat(4,1fr);
}
Alberto Valerio
  • 388
  • 2
  • 6
  • 18
2

::ng-deep will be deprecated in future yes. An alternative would be to import the CSS/SCSS file from the child.

parent-component.css

.header-logos-card {
  grid-template-columns: repeat(4, 1fr);
}

child-component.css

@import './path/to/parent-component.css';

More about Angular css imports here.

Eddie Reeder
  • 805
  • 1
  • 7
  • 13
1

The problem behind ::ng-deep is that it makes it a global selector, to prevent that you need always use :host before it.

According documentation:

Applying the ::ng-deep pseudo-class to any CSS rule completely disables view-encapsulation for that rule. Any style with ::ng-deep applied becomes a global style. In order to scope the specified style to the current component and all its descendants, be sure to include the :host selector before ::ng-deep. If the ::ng-deep combinator is used without the :host pseudo-class selector, the style can bleed into other components.

So correct answer would be:

:host {
  ::ng-deep {
    .header-logos-card {
      grid-template-columns: repeat(4,1fr);
    }
  }
}

Or alternatively importing it styles from child:

@import './path/to/parent-component.css';

and than using it like this:

:host {    
  .header-logos-card {
    grid-template-columns: repeat(4, 1fr);
  }
}
kamil
  • 41
  • 9
1

Ng deep is deprecated don't use it. Instead use both root level and component level sass. It works much easier. I have articles on this if you are interested.

JWP
  • 6,672
  • 3
  • 50
  • 74
0

This solution to the problem is this:

:host ::ng-deep app-operator-filter{
  .header-logos-card {
    grid-template-columns: repeat(4,1fr) !important;
  }
}

!important was a crucial addition as the changes were being overwritten without it.

Vasko Vasilev
  • 554
  • 1
  • 10
  • 25
0
  1. In the app-parent.component.ts file set viewEncapsoluation to none.

    import { Component,ViewEncapsulation} from '@angular/core';
    
    @Component({
       selector: 'app-parent-selector',
       templateUrl: './app-parent.component.html',
       styleUrls: ['./app-parent.component.css'],
       encapsulation:ViewEncapsulation.None
    })
    
  2. In the app-parent.component.css file wrap the child css class by the child selector.

    app-operator-filter {
      .header-logos-card {
        grid-template-columns: repeat(4,1fr);
      }
    }