a.j. a.j. - 7 months ago 12
Javascript Question

How are styles within div's made 'safer' (i.e. so they do not override parent styles)

I am implementing an email client. One of the problems that I am facing is the fact that displaying the emails (i.e. the body of the email) may interrupt the styles of the general web application (not just the div).

Say I have a JS variable:

var element = $(data.bodyHTML);
$('div.result').html(element);


Where
data.bodyHTML
is the HTML content of the email body which contains the following:

<html>
<head>
<style>
div, p, span, a {
padding: 0;
margin: 0;
color: black;
}
.test-div, .test-p, #test-strong {
color: blue !important;
}
</style>
</head>
<body>
<div class="test-div"><p class="test-p">Signature</p><strong id="test-strong">John Doe</strong></div>
</body>
</html>


The
div, p, span, a
style destroys the styling in the rest of the web app (as long as I remain on the same page).

I've tried everything to prevent it from happening. I can't use an iFrame. I seen other email clients doing something like so:

<html>
<head>
<style>
.SafeStyles div, .SafeStyles p, .SafeStyles span, .SafeStyles a {
padding: 0;
margin: 0;
color: black;
}
.SafeStyles .test-div, .SafeStyles .test-p, .SafeStyles #test-strong {
color: blue !important;
}
</style>
</head>
<body>
<div class="SafeStyles">
<div class="test-div"><p class="test-p">Signature</p><strong id="test-strong">John Doe</strong></div>
</div>
</body>
</html>


.SafeStyles is placed in front of each style tag/class/id so as to prevent any override to the parent.

But how is this being done? That is my question.

Any kind of help or suggestions are appreciated. Thanks.

EDIT: I think people here seem to misunderstanding my question. I know exactly why the styles are overriding the parent, I know enough CSS to understand the basics. The question is this:

Given a string of html in javascript, with javascript, how do you add classes before the styles within the style tag of the given html string?

Answer

Simple answer, given how CSS works: CSS doesn't care about where it's declared, it kicks in globally. If you have a rule div { ... } then that applies to all divs, everywhere in the document, and the only way to change what they do is to override properties with more specific rules.

And that's exactly what you do with div.classname: this does not apply to all divs, only to divs with a class classname. Want to be absolutely safe: add your own safety class(es) to each element, and declare CSS with selectors that rely on those:

<div class="personal safety">
  <p class="personal safety">
  </p>
</div>

and now we define the styles we want for these elements:

div.personal.safety { ... }
p.personal.safety { ... }

done, this CSS will only apply to our code.

Except only "sort of", because if you use this on a page that happens to already use "personal safety" as CSS classes, then you still end up with a conflict. The usualy trick is to come up with classes that are specific enough to your use that they won't collide.

And then the second problem of course is that any CSS value you don't explicitly set, you will keep inheriting from the owning document so if there's this in the owning document:

div { background: red }

and you use this for your specific snippet content:

div.personal.safety { font-family: fantasy }

then that will lead to your snippet content being a red div with fantasy font. Because you didn't change the background color for your snippet HTML.

This is all essentially "the basics of CSS" so I'd also strongly urge you to read up on how CSS works. Read an O'Reily book, or google for some tutorials (not w3schools or MDN examples of individual CSS rules, but proper "learn CSS" tutorials).

And read the links you got in the comments: security is no laughing matter, get that part right.