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 :
- create a new component and create a service to load dynamic css variables from API.
- Add style tag in template file and use variable values for properties.
- Load this template on all pages or on main template.
- 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:
- I haven't checked the styling part. But the gist of it is to use the ternary operator.
- Ideal solution here would be to write a pipe.
Related Topics
How to Use CSS3: :Selection Without Changing The Default Color and Background Color
Why Am I Unable to Apply a Border to an Angular Mat-Table Row
CSS Selector Wildcard Inside Class Name
Text Is Wrapping Under Bullet in CSS List
React Native: "Auto" Width for Text Node
Horizontally Center <P> Within a Div While Keeping The Text Left-Aligned
Is There a CSS Selector to Match a Option Value of The Select Tag
Please Explain Rowspan and Colspan, Col and Colgroup
0 as Saturation and Lightness Doesn't Work But 0% Does in Hsl/Hsla
Align Text to The Right of an Image && Text Doesn't Wrap Around The Image
Tailwind CSS + Vuejs Single File Component and Vs Code Integration
Correct Font-Display Value for Icon Fonts
How to "Hack" The Thunderbird Lightning Extension to Fully Color Categories
Bootstrap 3: How to Create Responsive, Square .Thumbnail Divs
Interruption of a CSS Transition Does Not Work for Same Attribute Value