Stencil: Shadow DOM support

Created on 29 Aug 2017  路  8Comments  路  Source: ionic-team/stencil

In https://github.com/ionic-team/stencil/issues/93 @jgw96 mentioned Shadow DOM is supported, but not totally recommended.

Could you talk through this a bit more? Based on some info @robdodson shared in a recent talk, there's an entire category of gnarly issues that can be avoided if you render inside a SD, such as applying styles when your CE is inside another shadowRoot. See slides: https://speakerdeck.com/robdodson/custom-elements-everywhere?slide=20

So mostly I'm curious whether Shadow DOM is something you'll be supporting more formally? Or has it not been something you've particularly needed?

Most helpful comment

Yeah I wish I had more time to get to this in my Polymer Summit talk. I actually wrote a whole section on why Shadow DOM still makes styling difficult, depending on your use case.

The short version is:

  • If you're building a general purpose UI library, meant to be themed by developers (think Twitter Bootstrap), then Shadow DOM is difficult to work with. That's because the only way to style across shadow boundaries is to use custom properties (aka CSS variables). But exposing a variable for every single property in your element doesn't scale. There's a new proposal called shadow parts that will hopefully fix this.
  • If you're building your own internal branded UI library (think Material Design at Google), then using shadow DOM is great because your company projects probably won't be doing major retheming. You might change a dominant color here or there, but otherwise you actually want all the components to look the same.
  • If you're just building one component that you want to share on a site like webcomponents.org then I'd suggest using shadow DOM _if_ it doesn't make your life too difficult. That might mean accepting the trade off that your element will not be completely rethemeable but it will work consistently in most environments.

All 8 comments

Hello! There is a long answer to this that should probably be put in a blog post or something similar, but ill try to condense into a short answer. The short answer:
Because of how our styling is done using sass, our styles are already scoped to each component. We have found that when building an app purely from stencil components, it's easier to style and compose elements without using shadow dom, for multiple reasons that are too long to put in a github reply haha. Now, if you're building web components using Stencil that are meant to be used in multiple projects, such as a video player, share button etc, shadow dom is a good answer. Hopefully this helps clear things up (:

Thx.

Yeah I wish I had more time to get to this in my Polymer Summit talk. I actually wrote a whole section on why Shadow DOM still makes styling difficult, depending on your use case.

The short version is:

  • If you're building a general purpose UI library, meant to be themed by developers (think Twitter Bootstrap), then Shadow DOM is difficult to work with. That's because the only way to style across shadow boundaries is to use custom properties (aka CSS variables). But exposing a variable for every single property in your element doesn't scale. There's a new proposal called shadow parts that will hopefully fix this.
  • If you're building your own internal branded UI library (think Material Design at Google), then using shadow DOM is great because your company projects probably won't be doing major retheming. You might change a dominant color here or there, but otherwise you actually want all the components to look the same.
  • If you're just building one component that you want to share on a site like webcomponents.org then I'd suggest using shadow DOM _if_ it doesn't make your life too difficult. That might mean accepting the trade off that your element will not be completely rethemeable but it will work consistently in most environments.

@robdodson I watched the video of your talk at Polymer Summit (on my list to try to attend assuming it happens next year), here is a direct link for anyone who hasn't seen it:

https://www.youtube.com/watch?v=sK1ODp0nDbM&list=PLNYkxOF6rcIDP0PqVaJxqNWwIgvoEPzJi&index=12

If I understood right, regardless of the styling issue you describe above, you more or less "must" use shadow DOM for components that have a nontrivial template (they create more elements inside to implement the desired functionality) and which have a slot. This category includes many or most "widgets". If you don't use shadow DOM, you can easily get the artifact you showed in talk with React (and which can happen with any other application framework).

Is that concern not as large as it seemed in your talk? Is that something to balance against the notion that non-shadow web components are much easier to integrate with styling at the point of use?

Is that concern not as large as it seemed in your talk?

It's definitely a concern but also depends largely on how your components are used. If your elements are mostly leaf nodes, then the framework may not be passing any children into them, in which case you wouldn't hit this. Another option would be to do your own distribution system using a mutation observer to fixup any issues created by the framework (example).

For what it's worth, when I tested Angular and Preact, they would just leave your children in place. However you still need to come up with a distribution system so they render in the correct spot. Also, as I said in the talk, there's nothing really _enforcing_ this behavior by these libraries. It's just a thing they've decided to do but you're kind of relying on that behavior never changing, whereas shadow dom gives you more of a guarantee of encapsulation.

Is that something to balance against the notion that non-shadow web components are much easier to integrate with styling at the point of use?

That's kind of hard to answer because I don't know if stencil does anything to try to fixup distribution. @adamdbradley can you speak to that?

If it provides its own workaround, or if you never really try to distribute framework children into the elements, then it may be totally fine.

So, will there be shadow dom support? Whether or not it's used should be up to each team/developer to decide, and if we aim for maximum cross-framework support, shadow dom is a must. without it, not even <slot>s seem to work properly

Yes there will be shadow dom support and it's currently on our todos: https://github.com/ionic-team/stencil/issues/151

Currently, without shadow dom, our slot distribution works as is and replicates the slot spec. As it stands, Ionic would not use shadow dom, however, stencil itself could or could not use it, depending on what the developer's choice (or at least that's the plan 馃槵 )

(Just re-read my last comment and realized I did a horrible job explaining it)

  • yes, stencil will support shadow dom
  • it's not done yet
  • developer can choose per component whether to use it or not
  • The UI library, Ionic, will not be using shadow dom in the near term
  • In the long run we hope to support it once the shadow parts spec hits (thanks for the reference @robdodson).
Was this page helpful?
0 / 5 - 0 ratings

Related issues

joewoodhouse picture joewoodhouse  路  3Comments

glemiere picture glemiere  路  3Comments

MatanYadaev picture MatanYadaev  路  3Comments

elmariofredo picture elmariofredo  路  3Comments

noahlaux picture noahlaux  路  3Comments