Jan Klan
Jan Klan

Reputation: 874

How to dynamically set complex CSS of an Angular 2+ component?

I'd like to ask for a little nudge to get my brain out of the box I got it into.

Context

Angular 4 using Angular CLI and AoT.

All methods mentioned in https://angular.io/docs/ts/latest/guide/component-styles.html describe ways to set complex CSS of a component while it is being written by a developer.

After a component is created, Angular allows to adjust individual styles and even assign various CSS class names to tags in the component as you please, all that using [ngClass], <div [class.something]="condition">, various @HostBinding decorators and some other methods.

However, none of the above can change the CSS declaration the component is using. The methods above can either (a) use what is already available in the stylesheet defined by the developer or (b) set individual CSS properties to individual HTML tags in the component's template.

Question

How would I update the CSS for the whole component on runtime so that all elements in that component respond to the new CSS?

Say I introduce a new style for a div.someClass and I want all matching elements div.someClass to reflect the new style.

Plunker

A showcase of my attempts is here: https://plnkr.co/edit/N2C40cSb7hd1AyOxWWdT

The button should be red, based on the value of MyChildComponent.styles

I think I understand why it doesn't work the way I would expect: shortly said, styles are built in the component during compilation, not runtime, including those found inside <style /> tags in the template.

But knowing why it doesn't work doesn't help me to make it work.

Any help highly appreciated.

Upvotes: 1

Views: 3735

Answers (1)

brijmcq
brijmcq

Reputation: 3418

Solution 1

Inserting a new css class is not possible ( as far as i know ) but you can insert css properties to your component dynamically. I modified your dynamicStyles() to this

 get dynamicStyles(): any{
    return {'background': 'red' };
  }

that returns an object instead of string because you will pass this object to ngStyle of your button.

In your template, I change the button like this

<button type="button"
 [ngStyle]="styles">
  Button
</button>

Here's a plunkr

Solution 2

This is something that I would not recommend but in your case it might be useful. You can add this

encapsulation: ViewEncapsulation.None

and the import

import {ViewEncapsulation} from '@angular/core'

to your @Component.You can leak your component's css so that you can use it on your child component. Then in your child component, add a [ngClass] in your button so that you can just pass a variable via @Input() if it should be red.

  <button type="button"
  [ngClass]="{'redButton': isButtonRed}"
  >Button</button>

And in your style.css

.redButton{
  background:red;
}

And in your main component.

 <div>
  <h2>Hello name</h2>
  <my-child [isButtonRed]="true"></my-child>
 </div>

Here's another plunkr

Hope this helps.

Upvotes: 3

Related Questions