In this post, we’ll look at how we can apply styles to html content rendered via innerHtml
attribute.
By default, styles defined in an Angular component only work in that specific component. This is due to the Emulated view encapsulation policy set by Angular.
This logical scope is great because styles of component A cannot affect component B. This is also the case where component B is a child of component A.
Table of contents
Example
In the following template, we want to apply styling the img
tag in the html content.
const content = '<img src=".." alt="..">'
<!-- Post page component html -->
<div [innerHtml]="content"></div>
Code language: HTML, XML (xml)
Unfortunately, the following CSS rule does not work because of the default view encapsulation policy.
img {
border: 1px solid red !important;
}
Code language: CSS (css)
Emulated view encapsulation is preventing styles from intercepting inside and outside of the component.
In this case, value bound to innerHtml
attribute is considered outside of the component. This is because the value of content
variable was not originally defined in your component HTML.
There are a couple of ways you can work around this issue. Let’s check out each solution.
Remove view encapsulation
#1 workaround is to change the view encapsulation of the component to ViewEncapsulation.None
@Component({
selector: 'app-post-page',
templateUrl: './post-page.component.html',
styleUrls: ['./post-page.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class PostPageComponent implements OnInit {}
Code language: TypeScript (typescript)
Please note that changing ViewEncapsulation to None can have pretty far-reaching consequences.
This applies your styles globally – so if you set something like a div tag to have a background color, this will change all divs in your app to have that background color.
I would steer clear of changing the ViewEncapsulation unless you absolutely have to.
Use ::ng-deep
A better solution is to use ::ng-deep
selector in each of your CSS rules.
:host ::ng-deep img {
border: 1px solid red !important;
}
Code language: CSS (css)
This styling above will now apply to images deep in this component.
It is important to limit the use of ::ng-deep
to only children of an encapsulated parent component. Otherwise, it would apply to all images in child components.
Using the :host
keyword before ::ng-deep
takes care of this.