简体   繁体   中英

inverse shadow dom, prevent css and js leaks from subtree to document

There is dynamic HTML content that I would like to include in my page. This is only HTML and CSS, no Javascript.

I have some global CSS styles and custom JS logic that needs to be applied to this dynamic content. Which means that I can't simply encapsulate it in an iframe. It should be in the same DOM as everything else.

But the dynamic content can define its own CSS, which I don't want to be applied to the global scope. Therefore I can't just set it as innerHTML on some div.

Here is a simple example, which sets it as innerHTML and pollutes global CSS ( jsfiddle ):

<!--this style needs to be global-->
<style>p {font-size:24px;}</style>
<p>Welcome, please take a look at this dynamic content:</p>

<!--custom elements need to be added here-->
<div id='placeholder'></div>


<script>
// the style in here must not be global
const dynamic=`
<p>dynamic html with fancy style :)</p>
<style>p {color:blue;}</style>
`
$("#placeholder").html(dynamic)
</script>

Now, with the shadow dom a similar problem is solved :

Shadow DOM lets you place the children in a scoped subtree, so document-level CSS can't restyle the button by accident, for example.

What I'm looking for is something like an inverse shadow DOM. Instead of shielding a local subtree from global styles, I want to shield the global styles from the local subtree. Is that possible? An important constraint is that custom javascript logic which also resides in global scope. The dynamic HTML should be accessible to jQuery, just like other elements.

Shadow DOM CSS isolation is two-ways. So with this technique you can "shield the global styles from the local subtree":

 // the style in here must not be global const dynamic=` <p>dynamic html with fancy style :)</p> <style>p {color:blue;}</style> ` placeholder.attachShadow( { mode: 'open' } ) .innerHTML = dynamic
 /*this style needs to be global*/ p {font-size:24px;}
 <p>Welcome, please take a look at this dynamic content:</p> <!--custom elements need to be added here--> <div id='placeholder'></div>

About JS, if you put it in a custom element class it won't leak anywhere else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM