Use :host-context and the ::ng-deep selector to apply context-based styling

Share this video with your friends

Send Tweet
Published 7 years ago
Updated 5 years ago

Often components need to be styled based on the context they are being placed in. In this lesson we will learn about how to apply styles conditionally to our component, based on our ancestor element styles using :host-context. In the very same way, we also explore how to leverage the /deep/ shadow DOM selector to target styles to child components.

Note that the ::ng-deep is only a temporary solution and is going to be dropped by Angular once there’s an official standard coming out. As such try to avoid using it.

[00:01] Assume we have this simple component here, and what we want is to apply some styling to our component, but to the actual host context styling -- to the host tag of our component -- but only if some of its ancestors has a specific styling tag.

[00:18] If our component here is wrapped in a div with styled component -- with a class that is named styled component -- then we want to have a border on our host context styling tag.

[00:32] We can go inside our component again -- here, we can use the style property -- and define that styled component style. We simply do something like one pixel, solid black, and display it block to see some styling.

[00:55] This isn't enough, because this style would only be valid within this component here, and it wouldn't be applied depending on some ancestor-styled class here. For instance, that styled component class.

[01:07] What we can do instead here is to use the host context meter tag and wrap our style in that tag. Now, if we save again, we can see how the style gets correctly applied to our component.

[01:23] In the very same manner, we may want to style some of our child components rather than our ancestors. For instance, take this simple child component here, which has a simple <p> tag inside there. If you now instantiate that child component within our host context component, we see that the component gets rendered properly.

[01:47] Now, one could go here and say we want to style all <p> tags with a background color of yellow. Again, as you can see, strange enough, this doesn't get applied to our child component. The reason is that this style here gets scoped only to this component here.

[02:09] Obviously, in Angular, there is a solution for applying such styles. What we can do here is to use the host selector, and then we can use the so-called /deep/ selector, which is also often called the shadow-piercing descendant combinator.

[02:24] What this special syntax here allows us is to escape the scoping of our component here and dive into the child component here and style tags inside there. If we save this, we can see that the style gets properly applied now.

[02:41] There is a problem associated with this /deep/ selector. It was initially introduced by the Blink team, but meanwhile, it has been deprecated by the W3C, and there is no standard so far.

[02:53] In order to avoid problems with other tools such as SASS and so on, which are going to deprecate that feature in there as well, the Angular team has introduced so-called ::ng-deep tag, starting from Angular version 4.3.1. As you can see here as well, the style gets correctly applied.

[03:13] As a general rule of thumb, you should try to avoid such /deep/ selectors whenever you can. If you really have to use them, start to use the ::ng-deep selector until there is some official standard coming out.

~ 7 years ago

The use of /deep/ is deprecated according to the official documentation.. I think you should at least mark it..

Juri Strumpflohner
Juri Strumpflohnerinstructor
~ 7 years ago

@Nadav Yep, your right, I just didn't manage to update in time. But I just uploaded a new video now that mentions this issue :) thx for highlighting this!

~ 7 years ago

Awsome! Thank you for the really fast update :)