Lets Build Web Components! Part 8: Mythbusters Edition

Benny Powers on February 18, 2019

So far in this series, we've covered the underlying web components standards, the legacy-browser polyfills, and their implementation with vanilla... [Read Full]
 

I understand why we can write web components. But why should we?
Are they currently faster?

 

You might have lots of motivations to use web APIs

  • Interoperability
  • Performance (both load and runtime)
  • Standardization
  • Vendor lock
  • You like the specific sugar offered by XYZ web components library or base class

Give this podcast a listen, they covered most of the major talking points.

pca.st/qY78

 
sloth-mascot Comment marked as low quality/non-constructive by the community View code of conduct

None at all.

There is NO w3c spec, there is no stability. This article is bullshit.

 

Tag @bennypowers , you coward :D
Jk, but who cares about w3c? Implementation is all that matters.
Like, I wish tail call optimization was implemented, but it isn't?
So I'm obviously not going to use it?

I wouldn’t respond t someone that being disrespectful... keep that in mind when responding

 

I really don't appreciate your language and personal insults.

There, i fixed it (i shouldn't have attacked you in person but i'm still super-triggered by this article, obviously i don't know your skills and therefore i can't be sure).

But i really don't appreciate you ignoring the w3c, inspiring other to do the same and basically lying about some points. Also reading the comments here is really eyeopening how backwards the current state of the web is, with companies trying to impose standards, people ignoring w3c. I can't stress enough how wrong and even dangerous this is.

specs, for the baseline, requisite parts of deploying web components today, and Proposals, for a lot of great future possibilities that are important to discuss as a community right now so our voices can be heard in the process, it's kind of how the w3c does its thing... It's a pretty beautiful process, even if its speed can leave you wanting at times. 😉Have you taken part in it before?

That is my point, but there is a big difference between discuss possibilities in the community and just saying: It's ready, just use it. And claiming that it is stable when it is totally not.

Companies are using it. That's what drives the browsers.
There are stats in the post.

Other than the Template Instantiation proposal, which of the technologies above aren't in the specs folder of that repo? Beyond that (which is noted very clearly as a proposal) everything else is 100% ready, as outlined in the article. What's more, discussion of the Template Instantiation proposal, and the benefits that will bring are have in the context of a production ready libraries that do similar work and specifically one that builds on the capabilities of the spec in anticipation of its arrival due to strong support across browser vendors and the developer community.

That is never a reason, and browsers should implement what w3c envisions, not the other way around.

Can you confirm for me what you think a proposal is?

It has been my understanding that the w3c doesn't make those internally, the community does. It just so happens in this case that some of the proposals came from the Chrome team at Google which had been spending a lot of time with devs and found some valuable additions to be made to the platform. In that case of Template Instantiation it comes predominately from Apple. In the case of HTML Modules, Microsoft.

Is the w3c not a consortium on many vested parties that together come up with the future of the web? You speak as the web we all work with is laid down as dogma from some shadow group.

Are you seriously suggesting browsers shouldn't focus on implementing anything and everything that is being massively polyfilled in the wild?

 

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>

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>

Note: this works fine on browsers with native support.

 

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?

 

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!

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.

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.

 

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.

 

Thanks for debunking these myths! I'm definitely keeping this around for the next time I run into these (an almost weekly occurrence).

My organization has been an early adopter of Web Components - we've had them in production for three years, and they've formed the core of our (wildly successful) design framework for two years. We keep running into these myths about them, but it's really fun to tell people that, if they're using the official theme, they're already using them and they just didn't realize it.

I wrote up some stuff about what we've been doing here, for those that are interested in what kinds of problems we tackled and how we dealt with them.

 

Can you provide an example of how you might pass complex data into a vanilla web-component via the HTML template?

I think the myth about web components not supporting complex data passing comes from folks having trouble doing React-style passing of props.

 
import { html, render } from 'lit-html';

const hobbitTpl = ({name, ability}) => html`
  <dt>${name}</dt>
  <dd>${ability}</dd>`

customElements.define('muh-hobbits', class extends HTMLElement {
  set band(val) {
    this.__band = val;
    if (!Array.isArray(val)) return;
    // Would be a great place to use template Instantiation when it lands
    render(html`<dl>${val.map(hobbitTpl)}</dl>`, this.shadowRoot)
  }

  get band() { return this.__band; }

  constructor() {
    super();
    this.attachShadow({mode:"open"})
  }
});

const main = document.querySelector('main')
render(html`<muh-hobbits .band=${[
  {name: 'Frodo', ability: 'courage' },
  {name: 'Samwise', ability: 'loyalty'},
  {name: 'Pippin', ability: 'strength'}
]}></muh-hobbits>`, main)


But at this point you might as well extend from lit element. It's vanilla enough.

 

That's sorta what I was trying to get at though. Lit is a light framework, but it would be nice to see an example of how one passes in rich data to a string literal web component template using nothing but the core spec. I think part of the reason this myth persists is because there's not a clear explanation about how to do it without resorting to tooling.

I have tried a bunch of different ways, but can't get past the fact that attributes have to be strings, and there aren't clearly explained ways to otherwise pass complex data into the component.

The closest I've gotten is to just use the slot system and require each page-level template to visibly nest component, so that arrays, as in your example, can be mapped in such a way that values land in their intended sub-component attributes as strings.

🤷‍♂️

Web component specs are not meant to solve every high-level concern for every use case. They're low-level primitives.

Libraries (in contradistinction to frameworks) like lit-html etc are there to build on the specs to provide high level uses.

Future primitives like Template Instantiation will let libraries like those be even smaller and more efficient.

This is a great point Samwise, there is a lot of ambiguity around this. I'm gonna show you one way that you can address this, but I'd be very interested in knowing whether you have a non-web component example of how this might be possible. Knowing what the explicit goals you might have is half the battle when it comes to architecting a useful solution. What I share below will be useful for some requirement, but likely not all, in this area.

In so far as you want a library free (except the polyfills) approach to passing rich data into a web component, I offer the following:

There are certainly things that could be said against this approach. In particular, the idea that JSON.parse() prevents the maintenance of identity is a big one. In response to that, I'd question how someone would actually rely on the idea of setting data as attributes beyond the initial load of a page. In that case, setting an initial identity that then can be maintained inside of the application by passing properties (theoretically you'd be in/have access to the JS scope at that point, so it would look like otherElement.customProperty = y) would absolve that issue.

What other use cases for communicating rich data between web components have you run into? I look forward to hearing about it! I think this is a really interesting part of the web components conversation, and techniques established and discovered in this area will benefit well beyond simply trying to set rich data on an element.

 

Well written. As a web-components evangelist I agree with everything you say.
I would mention Unit-Tests for web-components techniques.

You can read about my (working in production for several companies) tool here:
medium.com/.../easy-unit-tests-for...

 

Eu tinha tentando muito coisa, Vue, Angular, React, no primeiro momento parecia fantástico, mas quando você tentava utilizar puramente javascrip, tinha que me adaptar as regras de convenção destas ferramentas, quanto mais eu utilizavas estas ferramentas menos eu aprendia javascript, mas eu gostava da questão de componentização até conhecer web components e finamente chegar onde eu gosto, puro javascript eu crio as minhas regras o programador no controle novamente SHOW!!!! SHOW!!!! Muito Obrigado por este artigos, ainda ainda só estou dando uma passada , para estudar com calma cada linha!!!!!

 

some of these examples illustrate approaches that use build-time transpilation to render your templates (svelte in particular). But you aren't limited to that

That's not a limit, that's a superpower.

 

tl;dr: Web components 💓love💓 frameworks.

Especially Angular and Vue I see. React seems to be going in another direction...

 

footnote, preact has a much friendlier custom-elements support story

 
 
 

Wow this got me so triggered.

1) Web Components Aren't Supported By Browsers: True, only the newest ones support it, polyfill is no coverage at all. If you want a really Browser-support-table, use caniuse. This is the bull-shittiest visual ever made. Literally only the newest Firefox and Chrome have ok support, Safari and Opera have barely any support, Edge has no support whatsoever.

2 (Web Components Can't Accept Complex Data)) Mmkay...

3 (Web Components Have No Way Of Templating)) You are using external libraries for this, so actually the answer is: Yes, but very badly and it really hasn't been decided where they want to go with this.

4 (SSR)) So you mean, not very good

5 (Web Components are a Proprietary Google Technology) and 6 (You Need Polymer to Use Web Components)) Ok, i don't see why you find these important enough to make em into 2 points, but true, you don't have to.

7 (You Need to Use HTML Imports)) Ok, you are not wrong

8 (You Need Frameworks to Write Apps)) Ok, but you do need support to write apps, and ios does not really support it (i know your totally colored table about said something else but that is fake). This is not a point for WC but just against framework-idiots.

9 (You Can't Use Web Components in Frameworks)) Ok

Point 5 - 9 are just extremely logical, frequently unrelated with WC.

10) Ok, would be a very mediocre framework then.

Myth: The Web Community Has Moved on From Web Components:

No, not at all, but it's still far far far away, don't use it for production. Also really look at caniuse and be shocked by the real support i.e. caniuse.com/#feat=custom-elementsv1

Sorry man, did not want to be negative but this article can be extremely toxic for our job world. Why can't you just use something stable.

Any selfrespecting webdeveloper would hold this site as it's only source: w3.org/standards/techs/components#...

 

Regardless the fact that your comments are inappropriate and I think you should be banned for that, most of your arguments are wrong or irrelevant.

  • Web Components status page on w3c: w3.org/standards/techs/components#... and spec: html.spec.whatwg.org/multipage/cus...

  • Web Components supported by most of the modern browsers, and polyfill fill the gap for old ones, this concept allowed us running es2016 years ago, so why not using it? are you against babel? webpack?

  • Web Components aims to encapsulate state, functionality and DOM elements into one single module - truly MVC. who said it should allows you templating? you can build it via DOM api or other libraries.

  • I'm using Web Components inside my AngularJS old app, it works like a charm, boost the performance and made everything clean, testable and reusable.

 

So not agreeing is inappropriate, hmm, sorry not to be a part of your yes-sayers club.

  • Point one: Thx for defending me here because you will very clearly see that only html templates are completed, please use these yes

  • Point one is a very very bad one, first of all only the latest version of chrome and firefox is barely most of the modern browsers, because other browser don't support it or barely (don't look at this fake graph, look at caniuse).
    There is seriously something wrong if you look at the web like that. I don't believe in graceful degradation.

  • I did not find this an important point at all.

  • Lol Angular, ok 'nough said, nevermind.

So you apparently don't know what trolling means. Apparently not agreeing is trolling nowadays?

code of conduct - report abuse