Using CSS Variables In Angular

“Recently I was creating an Angular component where I was allowing the user to pass in a string to style a button. Then I would take that string and apply it using [ngStyle]=”buttonStyle”.
Very common to an Angular programmer.”

The Dilemma

 

“As part of the requirements, I needed to be able to pass into this component the color for the ‘hover’, ‘active’ and ‘focus’ pseudo-classes for the button. This is where ngStyle stopped working and I had to come up with a different solution. It doesn’t work because you can’t set pseudo-classes (:hover, etc.) on the style property of an element (i.e. <button style=”:hover {background-color: blue}”> —- does not work

 

Why doesn’t it work…? Because the pseudo-classes must be defined in CSS. Which is fine but how can you pass a variable to CSS using Angular? Let’s find out!

CSS Variables Primer

 

In short, the answer to my dilemma above was to use CSS variables (link). Let’s first learn the basics of CSS variables so we can understand how to use them in Angular.

A CSS variable takes this form:

:root {
    --hoverColor: white;
}
      • :root allows you to use this variable globally across the HTML document
      • –hoverColor is the CSS variable

Then to use the CSS variable, use the “var” function:

button:hover {
    background-color: var(--hoverColor, grey);
}
So in this case, the background-color will be “white” because –hoverColor is defined in the :root

      • If it isn’t defined, it will get the default “grey” value

How to Use the CSS Variable in Angular

 

So we learned about CSS variables but how do we take this knowledge and apply it to Angular? In other words, how can we pass a variable into the CSS so the CSS variable works? It turns out the answer depends on which version of Angular you are using.

Common Code

For both solutions, these things remain the same:

      • Define the “hoverColorVar” variable in the component Typescript:
export class AppComponent {
  // Note it is important to set this to 'null' here to get the default color in css.
  hoverColorVar: string = null;
}

      • Use the –hoverColor CSS variable in the component CSS for ‘background-color’:
button:hover {
    background-color: var(--hoverColor, grey);
}

      • Regardless of how –hoverColor is bound to hoverColorVar, the CSS uses the bound value at the element (button in this case) scope.
Version 9 and After

For version 9 and after, it’s quite easy:

<button type="button" [style.--hoverColor]="hoverColorVar">Press Me</button>
      • [style.–hoverColor] binds the hoverColorVar to the button style
      • This solution is how you would expect it to work in Angular

After all, something like this is common: [style.color]=”textColorVar”

Version 8 and Before

For version 8 and before, you just need to use the following directive (because [style.–hoverColor] was introduced in version 9 of Angular):

@Directive({ selector: "[bindCssVariable]" })
export class BindCssVariableDirective {
  @Input("bindCssVariable") variable: string;
  @Input("bindCssVariableValue") value: string;

  constructor(private host: ElementRef<HTMLElement>) {}

  ngOnChanges(changes) {
    const value = changes.value.currentValue;
    this.host.nativeElement.style.setProperty(`--${this.variable}`, value);
  }
}
      • Every time the bound value (bindCssVariableValue) changes, it calls setProperty on the style of the element, which binds bindCssVariableValue to the –hoverColor CSS variable

For the example above, you would use it like this:

<button type="button"
	bindCssVariable="hoverColor"
	[bindCssVariableValue]="hoverColorVar"
>
    Press Me
</button>

Examples and Sources

If you’d like to play around with this, check out the StackBlitz.
See Netanel Basal’s article, using the link below, which was used as a source.

Rich Franzmeier

Rich is a lead consultant, author, and another reason to consider Intertech when you need help on your project!

 

Let’s Build Something Great!

Tell us what you need and we’ll get back with you ASAP!