155

Let's say I have an Angular2 Component

//home.component.ts

import { Component } from 'angular2/core';

@Component({
    selector: "home",
    templateUrl: "app/components/templates/home.component.html",
    styleUrls: ["app/components/styles/home.component.css"]
})
export class HomeComponent {
    public width: Number;
    public height: Number;
} 

The template html file for this component

//home.component.html

<div class="home-component">Some stuff in this div</div>

And finally the css file for this component

//home.component.css

.home-component{
    background-color: red;
    width: 50px;
    height: 50px;
}

As you can see there are 2 properties in the class, width and height. I would like the css styles for width and height to match the values of the width and height properties and when the properties update, the width and height of the div update. What is the proper way to accomplish this?

13 Answers 13

360

Try this

 <div class="home-component" 
 [style.width.px]="width" 
 [style.height.px]="height">Some stuff in this div</div>

[Updated]: To set in % use

[style.height.%]="height">Some stuff in this div</div>
Sign up to request clarification or add additional context in comments.

6 Comments

Wow! Too simple!
Can you help me and tell me why [style.marginLeft.%]="this.triangleMargin" does not work? :( The other parts work like you showed us, thank you :)
If I want to perform operation , can i do like this, [style.height.px]="someVariable * 5"
to @Siminho don't use this. It's implied in the html template.
is there a way to be more programmatic like [style.width]="100px" or [style.width]="90%" meaning that I would set CSS like text value to indicate px or %
|
52

To use % instead of px or em with @Gaurav's answer, it's just

<div class="home-component" [style.width.%]="80" [style.height.%]="95">
Some stuff in this div</div>

Comments

19

This should do it:

<div class="home-component" 
     [style.width]="width + 'px'" 
     [style.height]="height + 'px'">Some stuff in this div</div>

2 Comments

How to make it work with method? [style.width]="getWidth()" getWidth() { return "100px" } doesn't work, tried "'100px'", nope and "100 + 'px'" nope
JS is tricky had to return without double quote like return '100px' or return '90%'
12

You can also use hostbinding:

import { HostBinding } from '@angular/core';

export class HomeComponent {
    @HostBinding('style.width') width: Number;
    @HostBinding('style.height') height: Number;
} 

Now when you change the width or height property from within the HomeComponent, this should affect the style attributes.

1 Comment

Would you explaining how to use those width and height vars ? and what is the diff b/w normal width: number and @HostBinding ?
11

If you want to set width dynamically with variable than use [] braces instead {{}}:

 <div [style.width.px]="[widthVal]"  [style.height.px]="[heightVal]"></div>

 <div [style.width.%]="[widthVal]"  [style.height.%]="[heightVal]"></div>

Comments

8

The accepted answer is not incorrect.

For grouped styles one can also use the ngStyle directive.

<some-element [ngStyle]="{'font-style': styleExpression, 'font-weight': 12}">...</some-element>

The official docs are here

Comments

7

Check working Demo here

import {Component,bind} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
import {FORM_DIRECTIVES} from 'angular2/form';

import {Directive, ElementRef, Renderer, Input,ViewChild,AfterViewInit} from 'angular2/core';

@Component({
  selector: 'my-app',
    template: `
    <style>
       .myStyle{
        width:200px;
        height:100px;
        border:1px solid;
        margin-top:20px;
        background:gray;
        text-align:center;
       }
    </style>

          <div [class.myStyle]="my" [style.background-color]="randomColor" [style.width]="width+'px'" [style.height]="height+'px'"> my width={{width}} & height={{height}}</div>
    `,
    directives: []
})

export class AppComponent {
  my:boolean=true;
  width:number=200px;
  height:number=100px;
  randomColor;
  randomNumber;
  intervalId;
  textArray = [
    'blue',
    'green',
    'yellow',
    'orange',
    'pink'
  ];


  constructor() 
  {
    this.start();
  }

      start()
      { 
        this.randomNumber = Math.floor(Math.random()*this.textArray.length);
        this.randomColor=this.textArray[this.randomNumber];
        console.log('start' + this.randomNumber);
        this.intervalId = setInterval(()=>{
         this.width=this.width+20;
         this.height=this.height+10;
         console.log(this.width +" "+ this.height)
         if(this.width==300)
         {
           this.stop();
         }

        }, 1000);
      }
      stop()
      {
        console.log('stop');
        clearInterval(this.intervalId);
        this.width=200;
        this.height=100;
        this.start();

      }
 }

bootstrap(AppComponent, []);

Comments

7

You can dynamically change the style(width and height) of div by attaching dynamic value to inline [style.width] and [style.hiegh] property of div.

In your case you can bind width and height property of HomeComponent class with the div's inline style width and height property like this... As directed by Sasxa

<div class="home-component" 
     [style.width]="width + 'px'" 
     [style.height]="height + 'px'">Some stuff in this div
</div>

For the working demo take a look at this plunker(http://plnkr.co/edit/cUbbo2?p=preview)

   //our root app component
import {Component} from 'angular2/core';
import {FORM_DIRECTIVES,FormBuilder,AbstractControl,ControlGroup,} from "angular2/common";

@Component({
  selector: 'home',
  providers: [],
  template: `
     <div class="home-component" [style.width]="width+'px'" [style.height]="height+'px'">Some this div</div>
     <br/>
     <form [ngFormModel]="testForm">
        width:<input type="number" [ngFormControl]="txtWidth"/> <br>
        Height:<input type="number"[ngFormControl]="txtHeight" />
     </form>
  `,
  styles:[`

      .home-component{
        background-color: red;
        width: 50px;
        height: 50px;
    }

  `],
  directives: [FORM_DIRECTIVES]
})
export class App {
  testForm:ControlGroup;
  public width: Number;
  public height: Number;
  public txtWidth:AbstractControl;
  public txtHeight:AbstractControl;

  constructor(private _fb:FormBuilder) {
      this.testForm=_fb.group({
        'txtWidth':['50'],
        'txtHeight':['50']
      });

      this.txtWidth=this.testForm.controls['txtWidth'];
      this.txtHeight=this.testForm.controls['txtHeight'];

      this.txtWidth.valueChanges.subscribe(val=>this.width=val);
      this.txtHeight.valueChanges.subscribe(val=>this.height =val);
  }
}

Comments

6

All the above answers are great. But if you were trying to find a solution that won't change the html files below is helpful

 ngAfterViewChecked(){
    this.renderer.setElementStyle(targetItem.nativeElement, 'height', textHeight+"px");
}

You can import renderer from import {Renderer} from '@angular/core';

2 Comments

Since this answer was posted, Renderer was deprecated. Use Renderer2 instead, and replace setElementStyle() by setStyle()
Nice! Its my choice
6

I liked the look of WenhaoWuI's idea above, but I needed to identify the div with class .ui-tree in the PrimeNG tree component to set the height dynamically. All the answers I could find required the div to be named (ie #treediv) to enable the use of @ViewChild(), @ViewChildren(), @ContentChild(), @ContentChilden() etc. This was messy with a third party component.

I finally found a snippet from Günter Zöchbauer :

ngAfterViewInit() {
  this.elRef.nativeElement.querySelector('.myClass');
}

This made it easy:

@Input() height: number;
treeheight: number = 400; //default value

constructor(private renderer: Renderer2, private elRef: ElementRef) {  }

ngOnInit() {
    this.loading = true;
    if (this.height != null) {
        this.treeheight = this.height;
    }   
}

ngAfterViewInit() {
    this.renderer.setStyle(this.elRef.nativeElement.querySelector('.ui-tree'), 'height', this.treeheight + "px");
}

Comments

6

you can achive this by calling a function also

<div [style.width.px]="getCustomeWidth()"></div>

  getCustomeWidth() {
    //do what ever you want here
    return customeWidth;
  }

Comments

3

In Html:

<div [style.maxHeight]="maxHeightForScrollContainer + 'px'">
</div>

In Ts

this.maxHeightForScrollContainer = 200 //your custom maxheight

Comments

2

My solution was a combination of the @ViewChild() and ngAfterViewInit() function.

HTML:

<div
  class="form-field text-form-field"
  #textInputContainer
>
  <label *ngIf="field?.label"> My Label </label>
  <input type="text"/>
</div>

TS:

  @ViewChild("textInputContainer") textInputContainer;

  constructor() {}

  ngOnInit(): void {}

  ngAfterViewInit(): void   {
    this.textInputContainer.nativeElement.style.width = "50%";
  }

Comments

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.