DEV Community

Discussion on: Lets Build Web Components! Part 8: Mythbusters Edition

Collapse
 
gugadev profile image
Gustavo Garsaky • Edited

Awesome and curated myth list, Benny! Currently, we are creating a design system in my company, but we are thinking in throw away using Web Components for a few but important reasons. Here are some of them.

1 - There is no way to access shadowed elements via CSS from outside (/deep/ and ::shadow selectors are deprecated and ::part is on draft yet). Yeah, this is a clear violation to the encapsulation principle, but, this is necessary in some cases. For example:

We have an <ck-icon> component. By default, it's color is dark gray (#333333). Theorically, this icon should inherit the color of the parent. Why? because, when it's inside an <ck-button> and the color is -for example- white, the icon should have the same color. Otherwise, the button will have a white color and the icon a gray one.

<!-- background: green; color: white -->
<ck-button kind="primary">
  <!-- color: gray; 😕 -->
  <ck-icon name="checkout"></ck-icon>
  <ck-text content="checkout"></ck-text>
</ck-button>
Enter fullscreen mode Exit fullscreen mode

2 - ShaddyCSS has some important limitations. For example, when using lit-element and want to apply styles from properties (using interpolation) it didn't works.

<style>
:host {
  ${importedStyles.toString()}
  <!-- property inside style tag is not reevaluated by Shaddy
       so, we can't override default styles -->
  ${this.props.color ? html`color: ${this.props.color}` : null }
}
</style>
Enter fullscreen mode Exit fullscreen mode

Note: this works fine on browsers with native support.

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦 • Edited

Yes those are important considerations, and shadow parts will solve many of them. In the mean time, one approach would be to slot in elements you need to style from light DOM. Alternatively, expose lots of custom properties.

As for interpolated styles, CSS custom properties and the style attribute are the preferred route for now. I expect to see some nice patterns emerge as Constructable Style Sheets gain traction.

As mentioned, you could also take the approach of not using shadow DOM, but I think that would be a loss.

WRT color, inherited properties should pierce shadow boundaries, so this sounds like a bug. Repro?

Collapse
 
thatjoemoore profile image
Joseph Moore

I've solved both of these problems using CSS Properties.

In their stylesheets, ck-icon and ck-text would both use a custom property:

  color: var(--ck-text-color, #333333);

Then, in ck-button (and any other element that manipulates the background color):

:host[kind=primary] {
  --ck-text-color: white;
}

We've solved your second problem by side-stepping it whenever we can - when we use attributes (like your 'kind'), we set styles based on the attribute values, often in the form of a bundle of CSS properties that get used elsewhere in the stylesheet.

For more dynamically-computed styles, though, you are kind of stuck. The Shady DOM polyfill stamps out its template and styles once for each element (I think this is done for reasons of performance). One thing we did was call back to the ShadyDOM polyfill with a different element name (my-element-{hash of state}) for each state we encountered (though you should be careful, as this can easily backfire). Or, you can, as Benny said, just set styles directly on the element. It's maybe not the prettiest solution, but it works!

Thread Thread
 
westbrook profile image
Westbrook Johnson

Joseph, my-element-{hash of state} is a really slick work around to the dynamic styling issue. The idea of "re-defining" your custom element on demand like that is actually pretty central to the way Skatejs approaches elements and their define package could be seen as a pretty fleshed out helper to intersect the two concepts.

Thread Thread
 
thatjoemoore profile image
Joseph Moore

So, we don't actually redefine the entire element, we just define a new template for ShadyDOM to play with. The actual code is here. I wouldn't reuse it verbatim, as it makes some assumptions that are very specific to us (like that, 99% of the time, our theme elements don't change their template once they've been stamped out the first time, so we don't need to worry about advanced diffing and such). We're also using a slightly older version of the polyfill, so it's possible that ShadyDOM has some new features that would get rid of some of this code.

Collapse
 
westbrook profile image
Westbrook Johnson

I've gotten stung by your point about the icon colors inheriting before as well. If you use SVG based icons, maybe we've been running into it for the same reasons. When I've had the issue you outline it's been because I've forgotten to use currentColor in my SVG attributes. It's easy to get an SVG that looks great out of the box and push it directly into my project, but if the fill or stroke or color attributes have fixed colors in them they'll quickly clash with some insertion point in my project. If you were interested in sharing a little more details in regards to your ck-icon elements, I'm sure we would both have something to learn from each other!

Benny's point about making sure to use things like color: inherit;, etc. is also really important as between the use of these two techniques and possibly CSS Custom Properties if absolutely needed, you should be able to maintain full control over your icon delivery, regardless of the context.