'Angular ngStyle for multiple styles

I am working on a simple animation library where my user can modify my component using property binding, so far I have been doing the following to apply their choices:

<div [style.background]="color" [style.width.px]="width" [style.height.px]="height"></div>

But for future additions I wish to change this whole mess with [ngStyle]="styleObject" to simplify adding more properties, I am trying to achieve this like such:

@Input() width: number;
@Input() height: number;

public styleObject: Object = {
    'height': this.height,
    'width': this.width
};

But for some reason <div [ngStyle]="styleObject"></div> is not taking into account the style shown above.

Please note that adding + 'px' and doing height.px does not solve my issue.

What am I not seeing?

--

A few tests have shown that

styleObject = {
    'height': 200 + 'px',
    'background': 'red'
};

works and is applied to the div, but that replacing 200 with this.height (of type number) does not.



Solution 1:[1]

When you using ngStyle you should create a function returning one of the following: a string, an array or an object.

if you want to return an Object you do the following:

in your template:

<div [ngStyle]="styleObject()"></div>

in your component:

export class AppComponent{
 styleObject(): Object {
       if (/** YOUR CONDITION TO SHOW THE STYLES*/  ){
           return {height: this.height,width: this.width}
       }
       return {}
   }
}

Solution 2:[2]

Try this approach

[ngStyle]="isTrue ? {width: '50px', height: '20px'} : {}"

Or

[ngStyle]="{
  width: '50px', 
  height: '20px'
}"

Solution 3:[3]

You can enumerate multiple style rules like this inside ngStyle:

<img src="..." [ngStyle]="{'height' : size+'px', 'width' : size+'px'}" />

Solution 4:[4]

I think Angular has started supporting unit. Working on Angular: 8.2.14.

The key is a style name, with an optional . suffix (such as 'top.px', 'font-style.em').

Now you can use [ngStyle]="{'width.px':200, 'height.px':200}"

Solution 5:[5]

If you define your styleObject like that this.height and this.width will be undefined. At the very least, define the styleObject in ngOnInit in which bindings will be guaranteed to be initialized.

For a more dynamic feel, where the user can change properties after the component has been rendered, you can use getters/setters.

It will look something like this:

export class YourComponent {    
  styleObject: {[key: string]: string} = {};

  @Input()
  set width(w: string) {
    styleObject = Object.assign({}, styleObject, {width: w});
  }
  get width() { return styleObject.width; }

  @Input()
  set height(h: string) {
    styleObject = Object.assign({}, styleObject, {height: h});
  }
  get height() { return styleObject.height; }
}

You can probably omit the getters, actually.

Solution 6:[6]

Try this approach [ngStyle]="{ backgroundColor: 'blue':'transparent', color: 'white'}"

Solution 7:[7]

The code below shows how to do multiple styles:

[ngStyle]="{'left' : calcWidth,'top' : calcHeight}"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Narendra
Solution 2
Solution 3 yglodt
Solution 4 Krishna
Solution 5
Solution 6 Nurak Chaisri
Solution 7 Stephen Ostermiller