cssangularangular-dom-sanitizer

Why are css rules not being applied to dom sanitized angular strings injected into html?


I have a very strange issue with a css rule not being applied when injected in html this is the code injecting the html:

decorate(text)
  {
    return this.sanitizer.bypassSecurityTrustHtml(text.replace('Doe','<b>Doe</b>'));
  }

in the template :

<h1 [innerHTML]="decorate('JohnDoe')"></h1>
<h1>Jane<b>Doe</b></h1>

I added a CSS rule for

h1 { color:#888; } 
h1 b {color:#ff0000;}

but still, JognDoe is grey while JaneDoe gets the Doe in red as expected. Why is Johns'Doe not rendered in red?

Rendered HTML looks like this in the inspector:

<h1 _ngcontent-c11="">John<b>Doe</b></h1>
<h1 _ngcontent-c11="">Jane<b _ngcontent-c11="">Doe</b></h1>

To me there is no reason for Johndoe to be grey..:

enter image description here

I assembled a small sandbox with the issue :

https://stackblitz.com/edit/angular-playground-pyjqju


Solution

  • Angular use ViewEncapsulation.Emulated by default. Which means CSS will apply to elements of the current component only. Due to this emulated encapsulation angular prevent style being applied to innerHTML element. You can fix this by changing emulated view to none.

    Try this:

    component.ts

    import { Component, ViewEncapsulation } from "@angular/core";
    import { DomSanitizer } from "@angular/platform-browser";
    
    @Component({
      selector: "my-app",
      styleUrls: ["./app.component.scss"],
      templateUrl: "./app.component.html",
      encapsulation: ViewEncapsulation.None
    })
    export class AppComponent {
      readonly name: string = "Angular";
      version: number = 7;
    
      constructor(private sanitizer: DomSanitizer) {}
    
      onVersionRelease(): void {
        this.version += 1;
      }
      decorate(text) {
        return this.sanitizer.bypassSecurityTrustHtml(
          text.replace("Doe", "<b>Doe</b>")
        );
      }
    }