3
<div [innerHtml]="someHtml | safeHtml"></div>

someHtml = '<span class="fas fa-calendar" style="font-size:15px"></span>'

I inject a html element through innerHtml property and I could apply some inline-style by binding DomSanitizer pipe. But I wonder if there's any other ways to apply styles through class other than inline-style with DomSanitizer. After some research, I could make it work with ::ng-deep but it seems deprecated according to the docs. Any insight would be appreciated!

DongBin Kim
  • 1,799
  • 5
  • 23
  • 43

2 Answers2

2

You could just set styles for that dynamic html in a global style sheet, instead of in a component's stylesheet. You just have to make sure that you target that dynamic part only, so that your styles don't leak to other elements

global.css

my-component div.dynamicContentWrapper span .fa-calendar
{
    font-size: 15px;
}

component.html

<div "class=dynamicContentWrapper" [innerHtml]="someHtml | safeHtml"></div>

Using ng-deep

::ng-deep is indeed tagged as deprecated in the documentation, but it won't go away before there is any replacement found

The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools.

What to use in place of ::ng-deep

component.css

:host ::ng-deep .fa-calendar {font-size: 15px; }
David
  • 33,444
  • 11
  • 80
  • 118
  • I haven't considered keeping the style of the dynamic html in the global style sheet! Thanks for sharing your insight :) Plus, I have also read their comments about `::ng-deep` and it doesn't seem to go away for a while but it will be gone eventually so I guess I won't go for it unless I have other option. – DongBin Kim Apr 12 '18 at 10:11
1

You can always change your component encapsulation to viewEncapsulation.None.

import { Component, ViewEncapsulation } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'my-app',
  template: `
    <div [innerHtml]="safeHTML(someHtml)"></div>
  `,
  styles: [`.red { color: red }`],
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
  someHtml = '<span class="red" style="font-size:18px">Hello</span>'

  constructor(private sanitizer: DomSanitizer) { }

  safeHTML(str: string) {
    return this.sanitizer.bypassSecurityTrustHtml(str);
  }

}

Live demo

Tomasz Kula
  • 16,199
  • 2
  • 68
  • 79
  • 1
    AFAIK, `ViewEncapsulation.None` option might possibly mess up the style of application because it makes the style visible throughout the application. Because of this reason, I didn't want to take this option. Am I missing something? – DongBin Kim Apr 12 '18 at 08:50
  • 1
    That is correct. The styles will be applied globally. But by using `[innerHTML]` you are moving outside of the angular component architecture, so I don't think there is a way to keep the encapsulation. – Tomasz Kula Apr 12 '18 at 08:54
  • 1
    You're right. I guess I've already broken sort of the encapsulation so setting ViewEncapsulation as none shouldn't be considered bad I guess. – DongBin Kim Apr 12 '18 at 10:13