How and where to use ::ng-deep?

假装没事ソ 提交于 2019-11-27 03:57:05

Usually /deep/ “shadow-piercing” combinator can be used to force a style down to child components. This selector had an alias >>> and now has another one called ::ng-deep.

since /deep/ combinator has been deprecated, it is recommended to use ::ng-deep

For example:

<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>

and css

.overview {
    ::ng-deep {
        p {
            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}

it will be applied to child components

::ng-deep, >>> and /deep/ are giving you access to DOM elements, which are not in your component's HTML. For example, if you're using Angular Material, some elements are generated by Angular Material outside of your component's area (such as dialog) and you can't access these elements using the regular CSS way. If you want to change the styles of those elements, you have to use one of those three things, for example:

::ng-deep .mat-dialog {
  /* styles here */
}

For now >>> and /deep/ are deprecated, so better use ::ng-deep.

UPDATE

"deep" manipulations are actually deprecated too, and before following this way, I recommend you to take a look at disabling CSS encapsulation approach (which is not ideal too) and decide, which way is better for your case. If you decided to disable encapsulation, it's really easy to achieve:

@Component({
  selector: '',
  template: '',
  styles: [''],
  encapsulation: ViewEncapsulation.None  // Use to disable CSS Encapsulation for this component
})

You can find more info in this article.

Make sure not to miss the explanation of :host-context which is directly above ::ng-deep in the angular guide : https://angular.io/guide/component-styles. Disclaimer: I missed it up until now and wish I'd seen it sooner.

::ng-deep is often necessary when you didn't write the component and don't have access to its source, but :host-context can be a very useful option when you do.

For example I have a black <h1> header inside a component I designed, and I want the ability to change it to white when it's displayed on a dark themed background.

If I didn't have access to the source I may have to do this in the css for the parent:

.theme-dark widget-box ::ng-deep h1 { color: white; }

But instead with :host-context you can do this inside the component.

 h1 
 {
     color: black;       // default color

     :host-context(.theme-dark) &
     {
         color: white;   // color for dark-theme
     }

     // OR set an attribute 'outside' with [attr.theme]="'dark'"

     :host-context([theme='dark']) &
     {
         color: white;   // color for dark-theme
     }
 }

This will look anywhere in the component chain for .theme-dark and apply the css to the h1 if found. This is a good alternative to relying too much on ::ng-deep which while often necessary is somewhat of an anti-pattern.

In this case the & is replaced by the h1 (that's how sass/scss works) so you can define your 'normal' and themed/alternative css right next to each other which is very handy.

Be careful to get the correct number of :. For ::ng-deep there are two and for :host-context only one.

I would emphasize the importance of limiting the ::ng-deep to only children of a component by requiring the parent to be an encapsulated css class.

For this to work it's important to use the ::ng-deep after the parent, not before otherwise it would apply to all the classes with the same name the moment the component is loaded.

Component css:

.my-component ::ng-deep .mat-checkbox-layout {
    background-color: aqua;
}

Component template:

<h1 class="my-component">
    <mat-checkbox ....></mat-checkbox>
</h1>

Resulting css:

.my-component[_ngcontent-c1] .mat-checkbox-layout {
    background-color: aqua;
}
Balázs Takács

Just an update:

You should use ::ng-deep instead of /deep/ which seems to be deprecated.

Per documentation:

The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools.

You can find it here

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!