Search code examples
angularcss-variablesangular-renderer

Angular: Use Renderer 2 to Add CSS Variable


Is it possible to add inline style css variable using Renderer2?

I tried the following but it doesn't work.

import { Component, OnChanges, Output, ViewChild, Renderer2, ElementRef, ViewEncapsulation } from '@angular/core';

@Component({
})
export class CollapsibleComponent implements OnChanges {

  @ViewChild('collapsibleContent') collapsibleContent: ElementRef;

  constructor(
    private renderer: Renderer2
  ) { }

  ngOnChanges() {
    this.measureCollapsibleContents()
  }

  measureCollapsibleContents() {
    this.renderer.setStyle(this.collapsibleContent.nativeElement, '--expanded', this.collapsibleContent.nativeElement.firstElementChild.offsetHeight + 'px' )
  }

}

'--expanded' isn't a proper css property so angular won't add any style to my div.

If I do add a proper css property it will work like the code below.

this.renderer.setStyle(this.collapsibleContent.nativeElement, 'top', this.collapsibleContent.nativeElement.firstElementChild.offsetHeight + 'px' )

the output for my div will be

<div style="top: 160px">...</div>

I would like to achieve something like below

<div style="--expanded: 160px">...</div>

I have also tried [ngStyle] but that also doesn't render any value but the style attribute.

[ngStyle]="{'--expanded': expandedHeight }"

Outputs to

<div style>...</div>

Solution

  • Angular sanitizes CSS variables set in property bindings. You can bypass this behavior with DomSanitizer.

    @Component({
      selector: 'my-app',
      template: `
        <button (click)="dec()">-</button>
        <button (click)="inc()">+</button>
    
        <div [style]="style"> My height is set by CSS Variable </div>
      `,
      styles: [`
        div {
          height: var(--height);
        }
        `
      ]
    })
    export class AppComponent {
      height = 50;
    
      get style() {
        return this.sanitizer.bypassSecurityTrustStyle(`--height: ${this.height}px`);
      }
    
      constructor(private sanitizer: DomSanitizer) { }
    
      inc() {
        this.height += 10;
      }
    
    
      dec() {
        this.height -= 10;
        if (this.height <= 0) {
          this.height = 0;
        }
      }
    }
    

    Live demo

    You might find this article interesting. It goes into details on theming Angular components with CSS variables.