I love custom elements! I've been building UIs with them since Polymer 0.5 was announced in 2014. One of the things that I've questioned with custom elements has been Shadow DOM and its relationship to CSS. This page is an experiment for comparing custom elements with and without Shadow DOM. Press the buttons below and 1,000 spinners will be displayed on the page, when 'Light' is pressed the custom element uses CSS defined for the whole page, and when 'Shadow' is pressed the custom elements have a style sheet attached to their Shadow DOM, and when 'External' is pressed the CSS for the element is still encapsulated in the Shadow DOM, but it is loaded as an external stylesheet.
N.B. I am not loading any polyfills on this page, so it will only work on browsers with native custom elements support.
This is the code that is running:
CSS
Javascript
The spinner-shadow
element follows the
suggested best practice
of encapsulating the styles via the shadow root. But this seems problematic
for a couple of reasons. The first is that it's going to be difficult to pass
that CSS through an autoprefixer or any other tooling. The second problem is
that this means the CSS will get duplicated for every instance of the element.
You can see that by looking in Chrome Dev Tools, that there are 3,000 more
nodes on this page when the shadow spinners are displayed as compared to when
the light spinners are displayed.
The spinner-external
loads the CSS in the Shadow DOM but uses an
external stylesheet, which does seem to reduce the number of nodes to below
that of the spinner-shadow
, but still not close to
spinner-light
. Also, I don't want to have a separate HTTP request
for every element class I use on a page, so this also seems like a
non-starter.
So am I holding it wrong? Is there really no way in custom elements to specify the CSS for an element once without resorting to external CSS stylesheets? Or am I reading the Chrome Dev Console page wrong and the Node count doesn't mean what I think it means? I think for now I'm going to stick to avoiding Shadow DOM and specifying the CSS just once in a single stylesheet.
Update: It does look like this is a known issue as there's a proposal to address it in custom elements spec.