219
votes

I have component in Angular 2 called my-comp:

<my-comp></my-comp>

How does one style the host element of this component in Angular 2?

In Polymer, You would use ":host" selector. I tried it in Angular 2. But it doesn't work.

:host {
  display: block;
  width: 100%;
  height: 100%;
}

I also tried using the component as selector:

my-comp {
  display: block;
  width: 100%;
  height: 100%;
}

Both approaches don't seem to work.

Thanks.

6
Are you sure the style is not applied? I've made a basic project and did exactly that and it worked. I've set my-selector { color : red} in my css and it works fine.Pacane
As of beta 7, the :host selector is working for me.Jon Swanson
@Pacane yes you are correct, it works perfectly fineNhân Nguyễn

6 Answers

308
votes

There was a bug, but it was fixed in the meantime. :host { } works fine now.

Also supported are

  • :host(selector) { ... } for selector to match attributes, classes, ... on the host element
  • :host-context(selector) { ... } for selector to match elements, classes, ...on parent components

  • selector /deep/ selector (alias selector >>> selector doesn't work with SASS) for styles to match across element boundaries

    • UPDATE: SASS is deprecating /deep/.
      Angular (TS and Dart) added ::ng-deep as a replacement that's also compatible with SASS.

    • UPDATE2: ::slotted ::slotted is now supported by all new browsers and can be used with `ViewEncapsulation.ShadowDom
      https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

See also Load external css style into Angular 2 Component

/deep/ and >>> are not affected by the same selector combinators that in Chrome which are deprecated.
Angular emulates (rewrites) them, and therefore doesn't depend on browsers supporting them.

This is also why /deep/ and >>> don't work with ViewEncapsulation.Native which enables native shadow DOM and depends on browser support.

50
votes

I have found a solution how to style just the component element. I have not found any documentation how it works, but you can put attributes values into the component directive, under the 'host' property like this:

@Component({
    ...
    styles: [`
      :host {
        'style': 'display: table; height: 100%',
        'class': 'myClass'
      }`
})
export class MyComponent
{
    constructor() {}

    // Also you can use @HostBinding decorator
    @HostBinding('style.background-color') public color: string = 'lime';
    @HostBinding('class.highlighted') public highlighted: boolean = true;
}

UPDATE: As Günter Zöchbauer mentioned, there was a bug, and now you can style the host element even in css file, like this:

:host{ ... }
11
votes

Check out this issue. I think the bug will be resolved when new template precompilation logic will be implemented. For now I think the best you can do is to wrap your template into <div class="root"> and style this div:

@Component({ ... })
@View({
  template: `
    <div class="root">
      <h2>Hello Angular2!</h2>
      <p>here is your template</p>
    </div>
  `,
  styles: [`
    .root {
      background: blue;
    }
  `],
   ...
})
class SomeComponent {}

See this plunker

10
votes

In your Component you can add .class to your host element if you would have some general styles that you want to apply.

export class MyComponent{
     @HostBinding('class') classes = 'classA classB';
6
votes

For anyone looking to style child elements of a :host here is an example of how to use ::ng-deep

:host::ng-deep <child element>

e.g :host::ng-deep span { color: red; }

As others said /deep/ is deprecated

3
votes

Try the :host > /deep/ :

Add the following to the parent.component.less file

:host {
    /deep/ app-child-component {
       //your child style
    }
}

Replace the app-child-component by your child selector