I have an Angular component named ExternalHtmlComponent responsible for rendering HTML content fetched from the backend. The HTML content is dynamically inserted into a element using the [innerHTML] property binding. To style the dynamically inserted HTML content, I’ve defined a mixin called external-html in the components/external-html.scss file. However these styles are not applied to tags.
How can I ensure that all styles defined in external-html.scss are correctly applied to the corresponding HTML elements within the dynamically inserted html ?
components/external/external_html.component.ts
import {Component, ViewEncapsulation, Input, OnInit} from '@angular/core';
@Component({
selector: 'component-external-html',
template: '<div [innerHTML]="html"> </div>',
styleUrls: ['./external-html.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ExternalHtmlComponent {
@Input() html: string;
constructor() { }
}
components/external/external_html.component.scss
@import "components/external-html";
:host {
@include external-html;
}
components/external-html.scss
@mixin external-html {
font: var(--font-body);
color: var(--color-text); // only these changes are applied, when inspected.
// if I add background color here, <a> tags gets it.
h1 {
font: var(--font-subtitle);
}
h2 {
font: var(--font-label-bold);
text-transform: uppercase;
color: var(--color-secondary);
}
h3 {
font: var(--font-emphasis);
}
b, strong {
font: var(--font-body-semibold);
background-color: red;
}
a {
font: var(--font-body-semibold);
color: var(--color-primary);
text-decoration: underline;
}
blockquote {
display: inline-flex;
justify-content: center;
align-items: center;
padding: var(--spacing-2);
border-radius: var(--border-radius-2);
background-color: var(--color-primary-05);
}
}
Here is the usage of it:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-external-html-example',
template: '<component-external-html [innerHTML]="exampleHtmlContent"></component-external-html>',
})
export class ExternalHtmlExampleComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
public exampleHtmlContent: string = `
<h1>This is a Heading 1</h1>
<h2>This is a Heading 2</h2>
<h3>This is a Heading 3</h3>
<p>This is a paragraph with <b>bold</b> text.</p>
<a href="#">This is a link</a>
<ul>
<li>Unordered list item 1</li>
<li>Unordered list item 2</li>
</ul>
<ol>
<li>Ordered list item 1</li>
<li>Ordered list item 2</li>
</ol>
<blockquote>
This is a blockquote with background color, padding, and rounded corners.
</blockquote>
`;
}
3
Answers
I resolved the issue by adding
::ng-deep
inSCSS
file of component.Also I saw that in some cases, you have to define the
encapsulation: ViewEncapsulation.None
But in my case it didn't matter.I can see a problem, you need to pass
[html]
instead of[innerHTML]
in the below line![innerHTML]
mostly destroyed the component so the styles did not get applied is my theory!The content rendered inside the
innerHTML
is not technically part of the component so we need to put the CSS insideglobal-styles.scss
then it will get applied to the innerHTML elements, there is no need forViewEncapsulation.None
!Stackblitz Demo
The :host selector only targets the host element of a component.
So, you need to wrap the style with the component’s css selector instead of host.
Try:
// styles.