0
votes

In order to learn the new concepts around Web Components, I am playing around with the polyfills provided by http://webcomponents.org/.

I don't want to use Polymer, but only the plain API. Also, I'm aiming to at least support Chrome, Firefox and IE in their latest versions.

I'm creating a custom element, "user-profile" using a template with the id "sdtemplate" which then is appended into the Shadow DOM:

<template id="sdtemplate">
      <style>
        p { color: orange; }  
      </style>
      <p>I'm in Shadow DOM. My markup was stamped from a &lt;template&gt;.</p>
    </template>

    <script>
     (function() {

     function searchInImports(selector){
        var links = document.querySelectorAll('link[rel="import"]');
        for(var link in links){
            if(links.hasOwnProperty(link)){
                var results  = links[link].import.querySelectorAll(selector);
                if(results.length > 0){
                    return results;
                }
            }
        }
     }

    var proto = Object.create(HTMLElement.prototype, {
      createdCallback: {
        value: function() {
            var t = searchInImports('#sdtemplate')[0];

            var clone = document.importNode(t.content, true);
            this.createShadowRoot().appendChild(clone);
        }
      }
    });
    document.registerElement('user-profile', {prototype: proto});

The element gets generated correctly but the CSS is applied differently to IE and Firefox from Chrome. Chrome shows the CSS correctly, only the <p> tag inside the template applies the CSS (thanks to the Shadow DOM) but in IE and Firefox, this CSS leaks and reaches other <p> elements outside of the template.

I tried to add the element name to the CSS selector:

      <style>
        user-profile p { color: orange; }  
      </style>

And it works for IE and Firefox but not for Chrome.

I'm guessing that even with the polyfills, IE and Firefox are not supporting the Shadow DOM.

Is there an easy way for me to use the Shadow DOM for supported browsers and have a fallback for unsupported browsers?

1

1 Answers

1
votes

Polyfilling shadow DOM style encapsulation would mean rewriting complete css in js, that's why polyfill doesn't even attempt it. As per docs this is a known limitation.

Is there an easy way for me to use the Shadow DOM for supported browsers and have a fallback for unsupported browsers?

Only way I can see to accomplish this would be to include a small script in the page which can prepend host-name in all selectors iff

  1. style is inside a template which will be later used to create a shadow root, and
  2. shadow dom is not natively supported.

To accomplish both of these, you just need to find if your style tag is inside a shadow root. Here is an excellent answer which tells you how to do that.