Vikram
Vikram

Reputation: 3351

Generate dynamic css based on variables angular

I'm trying to generate a dynamic css using values from json, I tried with following code in main component but its not working

@Component({
      templateUrl: 'card.html',
      styles: [`
        .card {
          height: 70px;
          width: 100px;
          color: {{css.cardColor}};
        }
      `],
})

How to we reference property values inside the styles declaration?

Edit : can not use ngStyle as its going to be applied on almost all elements as its for whole application and not only for specific element.

Upvotes: 58

Views: 206831

Answers (6)

Ajinkya Dhote
Ajinkya Dhote

Reputation: 1478

You can use ngStyle to dynamically add the css to your page from json.

<div [ngStyle]="{'color': variable ? 'red' : 'blue'}"></div>

An another example:

 <div md-card-avatar [ngStyle]="{'background-image': 'url(' + post.avatar + ')', 'background-size': 'cover'  }"></div>

here I have loaded background image from json-data.

Upvotes: 55

Vikram
Vikram

Reputation: 3351

Direct approach available in angular is using ngstyle as follows

<div [ngStyle]="{'color': style.colorVal ? style.colorVal : '#000', 'font-size' : style.fontSize ? style.fontSize : '16px' }"></div>

After going through different methods and approached to add dynamic css to all pages on angular app I ended up with following solutions.

Requirement : generate dynamic css based on values returned from and API to change design and styling.

Solution :

  1. create a new component and create a service to load dynamic css variables from API.
  2. Add style tag in template file and use variable values for properties.
  3. Load this template on all pages or on main template.
  4. On app build style will be moved to head tag.

Code sample

import { CssService} from './Css.service';

@Component({
  selector: 'DynamicCss',
  templateUrl: './DynamicCss.component.html',
  styleUrls: ['./DynamicCss.component.scss']
})
export class ServiceProviderComponent implements OnInit {
    cssVariables: any;
    constructor(private cssService:CssService){
        /* call the service/api to get the css variable values in cssVariables */

    }
}

Now apply css using jquery or javascript to append css with help of function like following

appendCss(customData)
{
     let text = '.custom-form-1 {
            background-image: url("`+customData.background_image+`");
         }';
     $(document).ready(function(){
         $("style").append(text);
      });
}

and call this function after loading custom data from service or other variable like I did it ngOnInit

ngOnInit(){
 this.appendCss(this.customizeFormData);
}

Its using jquery but can be done with javascript/typescript as well if you dont want to use jquery in your angular app

Other useful resource https://github.com/angular/angular/issues/9343#issuecomment-312035896

Upvotes: 38

Fahimeh Ahmadi
Fahimeh Ahmadi

Reputation: 1029

For background use, the JSON method is used for color:

<ion-list-header class="background-size"
[ngStyle]="{'background-image': 'url(' + data.headerImage + ')'}"
*ngIf="data.headerImage != null">

Upvotes: 2

Matt Saunders
Matt Saunders

Reputation: 4074

I wanted to dynamically style an element nested within a component, (specifically http://tb.github.io/ng2-nouislider/), so similar to the OP, ngStyle was not suitable.

My approach was to use a reference variable in my template (https://angular.io/api/core/ViewChild) to access the native element of the component and find the target child node using querySelector (https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).

The required style was then applied with Renderer 2. Example below and on https://stackblitz.com/edit/angular-r3bs1d.

import { Component, Renderer2, ViewChild, AfterViewInit } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: './app.component.html',
    styleUrls: [ './app.component.css' ]
})

export class AppComponent implements AfterViewInit  {
    backgroundColour = '#ff0000';
    constructor(private renderer: Renderer2) { }
    @ViewChild('parent', { static: false }) parent;
    ngAfterViewInit(){
        this.renderer.setStyle(this.parent.nativeElement.querySelector('.child'), 'background', this.backgroundColour);
    }
}

HTML:

<div #parent>
    <div class="child">Child Element</div>
</div>

For minor styling changes at least, I think this is a feasible solution.

Upvotes: 0

Eliseo
Eliseo

Reputation: 57929

You can bind only style.color:

<div class="card" [style.color]="cardColor">lorem ipsum</div>

Upvotes: 17

Rohan Fating
Rohan Fating

Reputation: 2133

ngClass is used to set the dynamic class basis of your variable value as below

Ts File Component:

@Component ({
    selector:'simple-comp',
    template:`   <ol class="breadcrumb">
        <li *ngClass="{'active': step==='step1'}" (click)="step='step1; '">Step1</li>
        <li *ngClass="{'active': step==='step2'}"  (click)="step='step2'">Step2</li>
        <li *ngClass="{'active': step==='step3'}" (click)="step='step3'">Step3</li>
       </ol>`
})

export class SimpleComponent {
    public step: string = 'step1'; // change value like step1, step2, step3
}

HTML Code:

<some-element [ngClass]="{'first': true, 'second': true, 'third': false}">
 ...
</some-element>

Upvotes: 6

Related Questions