5
votes

There's a lot of talk around and about about how to style web components.

For example, http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/ suggests that you can use the :host tag to target the component tag itself, while an injected stylesheet with say, h1, should encapsulate the h1 inside the component's shadow dom.

Which is great, and works in chrome.

...but it only works in chrome.

Visiting the url above in firefox doesn't show any of the fancy demo's; and indeed, they flat out don't work at all.

So.

https://github.com/polymer/platform is theoretically a polyfill that lets you use web components with browsers that don't have native support for all the features needed.

In theory this includes some limited support for CSS rules, see: http://www.polymer-project.org/platform/shadow-dom.html

However, practically speaking it doesn't work. At all.

What's going on here? How can we seriously claim that the platform.js polyfill is working and supports older browsers when you can't style your components?

The best solution I've seen to this is to require the component template to have a known root class node:

<template>
  <style>
    .foo .bar {
       ...
    }     
  </style>
  <div class='foo'>
     ...
     <div class='bar'>Hi</div>
  </div>
</template>
<style>  
  .foo .bar { 
    ...
  }
</style> 

Note that the stylesheet is duplicated both in the template and in the document root context; otherwise firefox, safari and IE styles do not work.

Is this really the level we're at with web component styling?

Am I missing something?

It really seems like this is much much further away from being usable than people are suggesting, even using the most recent versions of every browser.

Here's a pen I've been playing with http://codepen.io/shadowmint/pen/iyFxE that uses platform.js 0.3.4 and shows how this works only in chrome.

1

1 Answers

4
votes

Question is a bit old, but putting this answer here in case you didn't figure it out yet.

Shadom DOM polyfill doesn't attempt style encapsulation or fixing shadom dom related selectors in non-supported browsers.
This is the reason that other than :host/:content selectors and :host()/:host-context() pseudo-classes not working, you'll see style written inside shadow dom leaking on to the whole page.

The way you can make :host selectors work(?), is by rewriting css rules and replacing :host with tag name of host element.
If you have an x-element custom-element then something like this:

:host {
  opacity: 0.4;
  transition: opacity 420ms ease-in-out;
}
:host(:hover) {
  opacity: 1;
}
:host(:active) {
  position: relative;
  top: 3px;
  left: 3px;
}
/*Convert it to*/

x-element {
  opacity: 0.4;
  transition: opacity 420ms ease-in-out;
}
x-element:hover {
  opacity: 1;
}
x-element:active {
  position: relative;
  top: 3px;
  left: 3px;
}

This is what polymer does for :content selectors i.e. distributed child nodes.

I agree there is code duplication, but there is no other way I see in which you can make Firefox/IE/Safari understand what :host selectors mean.
Hope it helps.