8

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

6
  • What does foo = 'var(--primary)' evaluate to? Commented Oct 6, 2019 at 16:39
  • 1
    It's a CSS variable. If just dumped anywhere in the template as in {{foo}} it's just var(--primary). What I'm looking for is <div style="background-color: var(--primary)"></div> Commented Oct 6, 2019 at 16:45
  • The value of the var(--primary) is "#00f" Commented Oct 6, 2019 at 16:47
  • Possible to create a stackblitz? If you do a console.log(var(--primary)); in your component what does it print out? Commented Oct 6, 2019 at 16:59
  • This could help. Commented Oct 6, 2019 at 17:58

5 Answers 5

12

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)">
Sign up to request clarification or add additional context in comments.

1 Comment

is there any reference for this? thank you in advance
3

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>

1 Comment

I really don't want to override the variable's value in the component; in fact, I want it to stay "linked" to whatever the value of the variable currently is in the app itself. So that a "theme switcher" component can change what the color is site-wide and my swatch will change too.
3

the OP's stackblitz example works beside the fact the var is considered dangerously by the angular compiler.

this can be bypassed with the DomSanitizer

public bg = this.sanitizer.bypassSecurityTrustStyle('var(--brandcolor)');
constructor(private sanitizer: DomSanitizer) {}

see https://stackblitz.com/edit/angular-kerk9q?file=src/app/app.component.html

Comments

0

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.

Comments

-2

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>

4 Comments

@BrianOgden Please elucidate why. Thanks.
With your answer I the OP cannot dynamically change the color via the JSON file containing different colors
@Steve try now maybe? I edited the answer and it works on stackblitz
That put me onto the answer in my case: I return 'background-color': var(${this.variable} (in my app, the json key "variable" is like "--primary, --brand" etc.

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.