I have created an HTML email that displays correctly in a few email clients I've tested, but when I provide a preview of it on my page, the embedded styles in the innerHTML
impact the parent. It must be possible to avoid this because when I view the email in gmail it displays correctly without changing the style of gmail itself.
Here's some HTML that shows the problem (but displays with no side effects in gmail):
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
* { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; }
</style>
</head>
<body>
<pre style="white-space:pre-wrap;">Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
</body>
</html>
I'm using Angular 4 so I'm including it in my page this way:
<div [innerHTML]="myHtml | safeHtml">
</div>
...and safeHtml is just a pipe to bypass the Angular checks on the HTML I'm injecting:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
@Pipe({name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer:DomSanitizer){}
transform(html) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}
It works, in that it does show the html in the div, but the style info changes everything on the page. I get it - I'm literally using *
in my embedded style. ...but as I say, gmail manages to 'contain' this somehow so it doesn't restyle the parent elements. How do I accomplish this?
Ideally I'd like total style isolation - like I don't want the parent styles to be impacted by the child or the child styles to be impacted by the parent (which, it seems, is how gmail is behaving).
Update
Changing the HTML to the following had it working for email, and contained the CSS, but didn't work embedded in Angular:
<!DOCTYPE HTML>
<html class="my-class">
<head>
<style type="text/css">
.my-class * {
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
color: blue;
}
.my-class pre {
white-space:pre-wrap;
}
</style>
</head>
<body>
<pre>Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
</body>
</html>
This is because (it seems) the html
and body
tags are stripped out when you embed this in a div
(which makes some sense). So, just add a parent containing div
with the class and it all works - both embedded and in the email:
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
.my-class * {
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
color: blue;
}
.my-class pre {
white-space:pre-wrap;
}
</style>
</head>
<body>
<div class="my-class">
<pre>Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test Test test </pre>
</div>
</body>
</html>
The best approach as @petryuno1 advised is to use a component as it would scope the CSS/styles to only that component, but at a basic level can you apply a class to the <div [innerHTML]="myHtml | safeHtml"></div>
such as:
<div class="foo" [innerHTML]="myHtml | safeHtml"></div>
Then modify the css to target *
of the class instead if a component is not possible?
.foo * { font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; }
The class
property on that <div>
would remain regardless of modifications to innerHTML
.
Hopefully that helps!