The host & ::ng-deep Pseudo Selector

:host this selector will allow us to style the host element of the component itself. Example:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'au-fa-input', // THIS ELEMENT PROPERLY
  templateUrl: './au-fa-input.component.html',
  styleUrls: ['./au-fa-input.component.css']
})
export class AuFaInputComponent implements OnInit {

  @Input() icon: string;
  constructor() { }

  ngOnInit() {
  }

  get classes() {
    const cssClasses = {
      'fa': true
    };

    if (this.icon) {
        cssClasses['fa-' + this.icon] = true;
    }
    return cssClasses;
  }
}
<i class="icon fa" [ngClass]="classes"></i>
<input class="normal-input" type="email" name="email" placeholder="E-mail">
.icon {
  width: 20px;
  text-align: center;
  background: white;
  padding-left: 5px;
  padding-right: 2px;
}

:host {
  border: 1px solid lightgray;
  padding: 1px;
}

input {
  border: none;
  outline: none;
}

Result:

The :host pseudo-class selector

Sometimes we want to style the component custom HTML element itself, and not something inside its template.

Let's say for example that we want to style the app-root the component itself, by adding it, for example, an extra border.

We cannot do that using styles inside its app.component.css associated file, right?

This is because all styles inside that file will be scoped to elements of the template, and not the outer app-root element itself.

If we want to style the host element of the component itself, we need the special :host pseudo-class selector. This is the new version of our app.component.css that uses it:

/* styles applied directly to the app-root element only */
:host {
    border: 2px solid dimgray;
    display: block;
    padding: 20px;
}

The use of the special _nghost-c0 will ensure that those styles are scope only to the app-root element, because app-root gets added that property at runtime:

<app-root _nghost-c0="">
  ...
</app-root>

Combining the :host selector with other selectors

Notice that the can combine this selector with other selectors, which is something that we have not yet talked about.

This is not specific to this selector, but have a look for example at this selector, where we are styling h2 elements inside the host element:

/* let's add another style to app.conmponent.css */
:host h2 {
    color: red;
}

The ::ng-deep pseudo-class selector

If we want our component styles to cascade to all child elements of a component, but not to any other element on the page, we can currently do so using by combining the :host with the ::ng-deep selector:

:host ::ng-deep h2 {
    color: red;
}

So this style will be applied to all h2 elements inside app-root, but not outside of it as expected.

This combination of selectors is useful for example for applying styles to elements that were passed to the template using ng-content.

::ng-deep, /deep/ and >>> deprecation

The ::ng-deep pseudo-class selector also has a couple of aliases: >>> and /deep/, and all three are soon to be removed.

The main reason for that is that this mechanism for piercing the style isolation sandbox around a component can potentially encourage bad styling practices.

The situation is still evolving, but right now, ::ng-deep can be used if needed for certain use cases.

Last updated