What Is the Different Between :Host ,:Host() ,:Host-Context Selectors

What is the different between :host ,:host() ,:host-context selectors

:host

Is syntax for styling the host component.

:host(.element)

Is an experimental CSS pseudo-class function that selects the shadow host of the shadow DOM containing the CSS it is used inside (Reference)

:host-context

Is syntax for styling a specific class anywhere outside the current element. The class must already be applied to an element outside the scope of the current element.

More in-depth info on the context of Angular applications can be found in this blog post.

What is the use case of :host-context selector in angular

This answer explains the difference between host and host-context. Here is an example of host-context usage. Suppose you have a component that wraps an input and this input can be used inside two different components - table and dropdown. When inside a dropdown it should occupy 50% of the width, when in table - 100%. Now if you have these two components selectors defined like this:

<my-dropdown>
<my-table>

Then the styles for the input component can be defined like this:

:host-context(my-dropdown) input { width: 50% }
:host-context(my-table) input { width: 100% }

Scope of :host-context(.class) selector

:host-contexts checks class on host element same as :host and then ancestors as you know. So your tests works fine. Please don't forget that css property color is inherited to children.

Understanding the basics of :host-context

My understanding is that :host-context is like :host except you can pass it a selector, and it will only match if the shadow host matches that selector in the light DOM. So lets say you have a custom element my-element. You want to style this div background color: red, but only if the my-element is in an H1, because it shouldn't appear in an H1 and the red is a clear sign to the dev that they made a mistake.

You can do this:

:host-context(h1) { background-color: red }

And the red background will only show up if my-element is a descendent of an h1.

<h1>
<my-element></my-element> <!-- red! warning! -->
</h1>
<div>
<my-element></my-element> <!-- no red, a-ok -->
</div>

Cannot Understand the Use of :host in components in Angular2

What i have understood of host is that if i have a child component
inside a parent component and we want to style a child component from
the parent component we can use :host . and :host-context for
vice-versa

No, this is not what it used for.

:host selector comes from shadow DOM spec.

...This scoped subtree is called a shadow tree. The element it's
attached to is its shadow host.

In angular world, a component's template is a shadow tree. The component's element is a shadow host. So when you're defining styles for :host selector, the styles are applied to the component's element.

:host

In your example, if you defined styles in my-app component, the styles will be applied to <my-app> DOM element. This particular configuration:

:host(.mine){
color:red;
}

Will be applied to the host element that has .mine class:

<my-app class="active">

If you defined styles in app-ngrx component, the styles will be applied to <app-ngrx> DOM element, NOT <my-app>. This particular configuration:

:host(.mine){
color:red;
}

Will be applied to the host element that has .mine class:

<app-ngrx class="active">

:host-context

Now, :host-context is also applied to the host element, but the function (parenthesis) takes a selector that is checked not against the host element itself, but against all ancestors up to document root. If such element is found, the styles are applied.

For example, this selector

:host(.mine){
color:red;
}

matches such structure:

<my-app class="mine">

whereas, this selector:

:host-context(.mine){
color:red;
}

matches this structure:

<div class="mine">
...
<my-app>

This is useful, if you want to apply styles to components view (shadow root) conditionally. This makes h2 always bold:

h2 {
font-weight: bold;
}

whereas this

:host-context(.make-inner-components-bold) h2 {
font-weight: bold;
}

makes them bold only if your component is inside an element with class .make-inner-components-bold.

Why does the :host selector only work in chrome with platform.js?

Question is a bit old, but putting this answer here in case you didn't figure it out yet.

Shadom DOM polyfill doesn't attempt style encapsulation or fixing shadom dom related selectors in non-supported browsers.

This is the reason that other than :host/:content selectors and :host()/:host-context() pseudo-classes not working, you'll see style written inside shadow dom leaking on to the whole page.

The way you can make :host selectors work(?), is by rewriting css rules and replacing :host with tag name of host element.

If you have an x-element custom-element then something like this:

:host {  opacity: 0.4;  transition: opacity 420ms ease-in-out;}:host(:hover) {  opacity: 1;}:host(:active) {  position: relative;  top: 3px;  left: 3px;}/*Convert it to*/
x-element { opacity: 0.4; transition: opacity 420ms ease-in-out;}x-element:hover { opacity: 1;}x-element:active { position: relative; top: 3px; left: 3px;}

How to use :host-context selector in an ngClass condition?

In angular you should not make any logical decisions in the code based on the html content properties such as classes or attributes, but vice versa - you should render classes and attributes in html based on data bindings. That's the main idea of angular - rendering view based on data bindings. Component's code should not really care too much about view structure.

So, in this case if your class should be based on some external information you need to @Import() that data through data bindings into your component and then use component properties in the ngClass directive. Yes, it moves logic into the component instead of html/css, but that's where it's supposed to be anyway: in the model/controller code, not in the view markup. Also, this way it will be much more convenient to test such a component.

Using :host-context() with an adjacent sibling selector

:host() and :host-context() only accept a compound selector as their argument, and not a complex selector.

x-foo[active] + x-foo is a complex selector that contains two compound selectors, x-foo[active] and x-foo, separated by the adjacent sibling combinator. :host() and :host-context() can accept either compound selector, but not any combinators.

Unfortunately, because the shadow host's siblings do not exist in the shadow context, you won't be able to write something like x-foo[active] + :host. As a consequence, I don't think you will be able to accomplish what you're looking to do in a shadow context. (In the light context, of course, you can just write x-foo[active] + x-foo, but that defeats the purpose of prepackaging CSS into a web component.)

It's not clear to me why :host() and :host-context() weren't specced to allow complex selectors in the first place, since if they did, what you have would have just worked.



Related Topics



Leave a reply



Submit