250

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.

4
  • 3
    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. Commented Sep 29, 2015 at 23:21
  • 1
    As of beta 7, the :host selector is working for me. Commented Mar 1, 2016 at 21:45
  • Angular 2 Component styles Commented Feb 2, 2017 at 4:23
  • @Pacane yes you are correct, it works perfectly fine Commented Nov 30, 2020 at 9:01

6 Answers 6

343

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.

Sign up to request clarification or add additional context in comments.

16 Comments

@Component({selector: 'some-selector', template: 'xxx', styles: [':host { display: block; background-color: green; border: solid 1px red; }']}) export class SomeClass {}
@OndraŽižka can you elaborate more? This is pure CSS, how can it be inconsistent with CSS and itself?
Unless I have missed some important shift in CSS, /deep/ and >>> are not CSS.
They are deprecated, but that doesm't matter. They are emulated by Angular (rewritten), therefore they only work with ViewEncapsularion.Emulated (default) but not with Native.
In Angular 2.4.7 I am able to get :host { p { font-size: 80%; } } to work in a ...component.css file. As soon as I try to use it with styles: [:host { p { font-size: 80%; } }] it no-longer works. Very strange.
|
62

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{ ... }

4 Comments

I like this better than creating a dummy .root element, but I don't like that it sets these styles as inline (forcing a !important to override). There's got to be a better waayy :\
no, styling via host{} in a stylesUrl file does not work. needs :host.
how can we access component variable inside host? If i want to decide background-color dynamically? ':host { background-color: this.bgColor; }'
@PratapA.K Hi, you can use HostBinding derorator. You example will be: @HostBinding('style.background-color') private color = 'lime'; Google will find you many examples and articles.
12

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

Comments

11

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';

Comments

6

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

1 Comment

This seems to be most precise and subtle solution! Cheers!
3

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

2 Comments

What if you want a stylesheet like bootstrap in there instead of a single style?
I do not recommend this anymore as /deep/ is deprecated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.