I dont't know how to add to my component <component></component> a dynamic class attribute but inside the template html (component.html).

The only solution I found is to modify the item via "ElementRef" native element. That solution seems a little complicated to do something that should be very simple.

Another problem is that CSS has to be defined outside component scope, breaking component encapsulation.

Is there a simpler solution? Something like <root [class]="..."> .... </ root> inside the template.

0

9 Answers

This way you don't need to add the CSS outside of the component:

@Component({ selector: 'body', template: 'app-element', // prefer decorators (see below) // host: {'[class.someClass]':'someField'} }) export class App implements OnInit { constructor(private cdRef:ChangeDetectorRef) {} someField: boolean = false; // alternatively also the host parameter in the @Component()` decorator can be used @HostBinding('class.someClass') someField: boolean = false; ngOnInit() { this.someField = true; // set class `someClass` on `<body>` //this.cdRef.detectChanges(); } } 

Plunker example

This CSS is defined inside the component and the selector is only applied if the class someClass is set on the host element (from outside):

:host(.someClass) { background-color: red; } 
11

Günter's answer is great (question is asking for dynamic class attribute) but I thought I would add just for completeness...

If you're looking for a quick and clean way to add one or more static classes to the host element of your component (i.e., for theme-styling purposes) you can just do:

@Component({ selector: 'my-component', template: 'app-element', host: {'class': 'someClass1'} }) export class App implements OnInit { ... } 

And if you use a class on the entry tag, Angular will merge the classes, i.e.,

<my-component> I have both someClass1 & someClass2 applied to me </my-component> 
13

You can simply add @HostBinding('class') class = 'someClass'; inside your @Component class.

Example:

@Component({ selector: 'body', template: 'app-element' }) export class App implements OnInit { @HostBinding('class') class = 'someClass'; constructor() {} ngOnInit() {} } 
2

If you want to add a dynamic class to your host element, you may combine your HostBinding with a getter as

@HostBinding('class') get class() { return aComponentVariable } 

Stackblitz demo at

Another problem is that CSS has to be defined outside component scope, breaking component encapsulation

This is not true. With scss (SASS) you can easily style the component (itself;host) as so:

:host { display: block; position: absolute; width: 100%; height: 100%; pointer-events: none; visibility: hidden; &.someClass { visibility: visible; } } 

This way the encapsulation is "unbroken".

1

for multiple classes situation, as @jbojcic mentioned above, you can use:

host: {class: 'A B C'}

In addition to @JoshuaDavid answer, there is another way to define static class, which works on angular v8 when I tried (might also work on older versions):

@Component({ selector: "my-component.someClass1.someClass2", ... }) 

which will generate following output:

<my-component> ... </my-component> 

you can also just use this way:

@Component({ selector: ".someClass1.someClass2", ... }) 

which will generate following output:

<div> ... </div> 
1

this is what I did:

import { Component, Attribute, HostBinding } from "@angular/core"; @Component({ selector: "selector-el", template: ... }) export class MyComponent { @HostBinding('class') get classAttribute(): string { let defaultClasses = 'selector-el-class'; return defaultClasses + ' ' + this.classNames; } constructor( @Attribute('class') public classNames: string ) { } } 
1

Here's how I did it (Angular 7):

In the component, add an input:

@Input() componentClass: string = ''; 

Then in the component's HTML template add something like:

<div [ngClass]="componentClass">...</div> 

And finally in the HTML template where you instance the component:

<root componentClass="someclass someotherclass">...</root> 

Disclaimer: I'm fairly new to Angular, so I might be just getting lucky here!

1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy