I need a web component that will not allow styles to bleed out of the Shadow DOM in IE 11 or Edge. Inline styles will work, but I need to use stylesheets.

I've tried everything including standard web components, polymer/LiteElement, react-shadow-dom-component and plain old JS. The code I'm attaching is very basic. This example doesn't use stylesheets, and it still bleeds over. I've tried multiple polyfills. I've also tried loader with defer and async. Any help is greatly appreciated.

<!DOCTYPE html>
<html>
<head>

<meta charset="utf-8">
<title>hello-world</title>

<!-- Imports polyfill -->
<!--<script src="../webcomponentsjs/webcomponents.min.js"></script>-->
<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents- 
bundle.js"></script>
<script src="https://unpkg.com/@webcomponents/[email protected]^2/"> 
</script>

<!--<script src="node_modules/custom-elements-es5-adapter/custom- 
elements-es5-adapter.js"></script>-->
<!-- Imports custom element -->
<!--<link rel="import" href="hello-world.html">-->
<!--<script src="shadowComponent.js"></script>-->
<style>

    .text {
        color: red;
    }
</style>

</head>
<body>

<div class="text">I should be red.</div>

<div id="myText"></div>

<script type="text/javascript">
    var element = document.getElementById('myText');
    var styles = '.text{color: blue; }';

    var content = 'I should be blue.';

    var style = document.createElement('style');
    style.type = 'text/css';
    style.appendChild(document.createTextNode(styles));

    var p = document.createElement('p');
    p.className = 'text';
    p.appendChild(document.createTextNode(content));

    var shadowRootContainer = element.attachShadow({ mode: 'open' });
    var innerContainer = document.createElement('div');
    shadowRootContainer.appendChild(innerContainer);

    var shadowRoot = innerContainer.attachShadow({ mode: 'open' });

    shadowRoot.appendChild(style);
    shadowRoot.appendChild(p);

</script>
</body>
</html>

There is a nested Shadow DOM in this example because I was at my wits end and decided to throw some code at the wall to see if anything would stick. I know that order matters in styles. I expect that with the polyfills this should work. It works in Chrome (obviously) FF, and Opera. I have more complex examples if necessary. Again any help is greatly appreciated.

2 Answers

3
Intervalia On Best Solutions

There is no shadowDOM in IE11 or Edge (pre-chromium). So there is no built-in way to prevent shadowDOM penetration.

If you use something like BEM or some other way of name-spacing your CSS selectors you can limit the penetration.

0
abraham On

You can mostly emulate ShadowDOM scoped CSS with the ShadyCSS component of the webcopmonentsjs polyfill. There are some limitations and it will only contain CSS within the component, it won't prevent external styles from leaking in.