Search code examples
google-chromepolymerpolymer-1.0web-component

Polymer - Internal elements visible in Chrome's elements browser


I just started learning Polymer, and I've been working through their docs. I have created a very simple Hello World element that seems to be working for me:

<link rel="import" href="/path/to/polymer/polymer.html">

<dom-module id="test-element">
    <template>
        <style>
            p {
                color: blue;
            }
        </style>
        <p>Hello [[name]]!</p>
    </template>
    <script>
        Polymer({
            is: 'test-element',
            properties: {
                name: String
            }
        });
    </script>
</dom-module>

I can import and use the element on a page successfully:

<link rel="import" href="/path/to/my/test-element.html">
<test-element name="World"></test-element>

That correctly shows a blue 'p' element saying "Hello World!", and I can also see that the CSS styling on the element is correctly not bleeding into other 'p' elements on the page outside of the element.

So far so good. However, in the docs I've been reading that one of the benefits of a web component is that its internal implementation details are hidden from the main DOM tree. Their given example was the 'video' element, which has other elements inside it, but you can't query those directly.

In the Chrome developer tools, however, I am able to see the 'p' element in the DOM tree inside my 'test-element'. I can even query it with jQuery, which I thought I was not supposed to be able to do:

$("test-element p")
// Produces: [ <p class="style-scope test-element">Hello World!</p> ]

Am I doing something wrong, or have I misunderstood the way Polymer works?


Solution

  • The reason behind what you see is shady-dom. Polymer by default implements shady-dom instead of shadow-dom(also the reason why we use lite version of webcomponentsjs, no shadow-dom present) as out of 3 major browsers (chrome, safari and firefox) currently only chrome has support and shadow-dom and using shadow-dom from polyfill(webcomponentsjs) is very costly (and some other reasons). shady-dom has its own downsides which includes the one that you observed and some other. You can read more about shadow and shady dom here.

    Note: You can still see shadow-dom's inner element in your chrome dev-tool if you enable Show user agent shadow DOM option in devtool settings, but this time with a different NodeList structure.

    For those browsers that do support it (i.e. Chrome), you can enable Shadow DOM when it is present by setting the global 'dom' Polymer setting to 'shadow' (see the Polymer Docs for more details):

    window.Polymer = {
      dom: 'shadow'
    };