Change CSS Variables Dynamically in Angular

Change css variables dynamically in angular

You can update them using

 document.documentElement.style.setProperty('--theme-color-1', '#fff');

If u want to update many values, then create a object

 this.styles = [
{ name: 'primary-dark-5', value: "#111" },
{ name: 'primary-dark-7_5', value: "#fff" },
];

this.styles.forEach(data => {
document.documentElement.style.setProperty(`--${data.name}`, data.value);
});

The main thing here is document.documentElement.style.setProperty. This line allows you to access the root element (HTML tag) and assigns/overrides the style values.

Note that the names of the variables should match at both places(css and js files)


if you don't want to use document API, then you can use inline styles on HTML tag directly

    const styleObject = {};

this.styles.forEach(data => {
styleObject[`--${data.name}`] = data.value;
});

Then In your template file using ngStyle (https://angular.io/api/common/NgStyle)

Set a collection of style values using an expression that returns
key-value pairs.

<some-element [ngStyle]="objExp">...</some-element>
<html [ngStyle]="styleObject" >...</html>  //not sure about quotes syntax

Above methods do the same thing, "Update root element values" but in a different way.

When you used :root, the styles automatically got attached to HTML tag

Generate dynamic css based on variables angular

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

Angular2 dynamic change CSS property

Just use standard CSS variables:

Your global css (eg: styles.css)

body {
--my-var: #000
}

In your component's css or whatever it is:

span {
color: var(--my-var)
}

Then you can change the value of the variable directly with TS/JS by setting inline style to html element:

document.querySelector("body").style.cssText = "--my-var: #000";

Otherwise you can use jQuery for it:

$("body").css("--my-var", "#fff");

Change the CSS4 variables dynamically

This is the theme switcher I have used.

import { Injectable, Inject } from '@angular/core';
import { DomController } from '@ionic/angular';
import { DOCUMENT } from '@angular/common';

@Injectable({
providedIn: 'root'
})
export class ThemeSwitcherService {

constructor(private domCtrl: DomController,
@Inject(DOCUMENT) private document) { }

setTheme(data: string): void {

switch (data) {
case "com1":
this.domCtrl.write(() => {
this.document.documentElement.style.setProperty("--ion-color-primary", "rgb(180, 151, 90)");
});
break;
case "com2":
this.domCtrl.write(() => {
this.document.documentElement.style.setProperty("--ion-color-primary", "rgb(129,147,171)");
});
break;
default:
}

}
}

This helped me a lot : Theme Switcher

Dynamically set scss variables angular ionic

SCSS is compiled to CSS during compile time, and SCSS variables are replaced with resolved value during compile time, which means there is no way to change the variable during run time. However css variables just sits there and you can easily change them,

for instance:

:root{
--dynamic-colour: #5260ff
}

now you can change its value from your component like:

changeColor(color:string){
document.documentElement.style.setProperty('--dynamic-colour', color);
}

Also you can assign --dynamic-colour to your scss variable as well so you wont have to do change in multiple places:

$dynamic-colour: var(--dynamic-colour);

STACKBLITZ WORKING DEMO

Dynamic css in angular with condition?

If the condition needs to satisfy all the objects in the array, I'd say it's better to introduce an additional variable that holds the condition as a boolean. You could use Array#every to check the condition.

Controller (*.ts)

export public SomeComponent implements OnInit {
allMain: boolean = false; // <-- boolean to hold condition

ngOnInit() {
// initialize `selectedItems`
this.allMain = this.selectedItems.every(item => item['main'] === 'someValue');
}
}

Use ternary operator in the template to apply the condition.

Template (*.html)

<tr *ngFor="let item of selectedItems; let i = index">
<td [style.padding-left.px]="allMain ? [5 * (i+1)] : 5">{{item.num}}</td>
</tr>

Note:

  1. I haven't checked the styling part. But the gist of it is to use the ternary operator.
  2. Ideal solution here would be to write a pipe.


Related Topics



Leave a reply



Submit