Using css variable in Angular template HTML?

Viewed 7649

I have a component that sets the background color of a div based on a value stored in a json file, which I then loop through to show a bunch of color swatches.

   <div class="color-swatch-color"
        [style.background-color]="foo"></div>

It works fine with a hex color in the variable: foo="#f00";

But no color shows up what I use a color variable: foo = 'var(--primary)';

The div shows in the HTML, no errors are thrown, but there is no background-color at all on the div.

UPDATE

I should be clearer. I have a theme that uses variables like --primary, --secondary (like Bootstrap). I want to show swatches with those colors. However, I use the variables in my CSS classes so that I can can change their value with a "theme" class on the body tag.

So I am trying to set my swatches to the variables so that when the user changes the class on the body tag, the swatch changes color automatically like the rest of my app.

Take a look at this stackblitz. If I assign the var directly, it assigns the background color. Via the angular variable it doesn't assign any color.

I am doing it this way because if you open dev tools, you can select my brandcolor variable and change it on the fly; this is similar to switching themes, where "brandcolor" can vary accoss themes

5 Answers

Css variables and Angular

If using Angular version 9+ (or 8+ ...not sure) you can do the following:

[style.<css-variable>]="<value>"

Example:

<div [style.--my-color]="myValue">
div {
  background: var(--my-color)
}

Cool isn't it? And pretty powerful too!

For you guys using older versions, the same can also be achieved with a little bit more of code:

inject DOMSanitizer in the class constructor and use it like this:

<div [attr.style]="sanitizer.bypassSecurityTrustStyle('--custom: ' + value)">

You will need inline CSS to use CSS vars and Angular interpolation, I think this will work:

Here is example of declaring a CSS var inline dynamically using Angular interpolation

<!--HTML-->
<html style="--color: {{myAngularVar}}"> <!-- declare a variable inline use Angular interpolation the value of myAngularVar is imply string/text the browser will parse as CSS code -->

And using a variable based on Angular string/text interpolation, I used foo as that is the name of your Angular variable in your question

<!--CSS-->
<style>
    div.color-swatch-color {  
        background-color: var({{foo}}) //another example
    }
</style>

When binding a custom CSS variable via [style.--feat-image]=...' or [ngStyle]=“{‘--feat-image’: … }” the property is ignored by angular and not bound. This is to avoid security issues.

If you trust those styles you could do the following:

1. Create a pipe to bypass the styles (tell Angular they are trustworthy)

@Pipe({name: 'safe'})
export class SafePipe {
    constructor(sanitizer: DomSanitizer){
        this.sanitizer = sanitizer;
    }

    transform(style) {
        return this.sanitizer.bypassSecurityTrustStyle(style);
    }
}

2. In the html use the pipe like this

<div [style]="'--percentage: ' + percentage | sanitize"></div>

This has worked for me in Angular 8.

EDIT: How about this?

https://stackblitz.com/edit/angular-kfeihc

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';

  bg = 'var(--brandcolor)';

  setStyle() {
    return {
      'background-color': this.bg
    }
  }
}
<div class="swatch" [ngStyle]=setStyle()>{{bg}}</div>
Related