
The Power of Web Components - lainon
https://hacks.mozilla.org/2018/11/the-power-of-web-components/
======
kyledrake
This is a bit off topic, but I really wish the idea of including HTML imports
([https://developer.mozilla.org/en-
US/docs/Web/Web_Components/...](https://developer.mozilla.org/en-
US/docs/Web/Web_Components/HTML_Imports)) was taken seriously. There's a lot
of people that just want to make a simple HTML site with templates for things
like the navigation menu, without a bunch of nasty JavaScript goop that can't
be search indexed easily, and the ability to include simple templates using
HTML would have been an huge resource for those people and for search engines.

I think it really shows how much of a bubble the web often lives in now. We
used to be able to just make a solid web site with simple HTML and a text
editor. I shouldn't need to be an extremely hardcore JS programmer or use a
crazy static site generator or overengineered LAMP backend to do basic things
like reusing HTML and other things that could be largely accomplished with
just HTML itself.

~~~
spankalee
HTML Modules are the spiritual successor to HTML Imports that work with the
standard JS module loading system:
[https://github.com/w3c/webcomponents/issues/645](https://github.com/w3c/webcomponents/issues/645)

~~~
styfle
For those following along at home, the reason why you don't need HTML Imports
once JS Templates and Modules exist is because HTML Imports are not usable
without JS! So you can implement a more elegant solution yourself with a
couple lines.

Let's assume you want to use 3 different HTML templates on a page (the html
content doesn't matter much for this example).

Here's the example usage of HTML Templates from html5rocks.com:

    
    
      <script>
        function handleLoad(e) {
          console.log('Loaded import: ' + e.target.href);
        }
        function handleError(e) {
          console.log('Error loading import: ' + e.target.href);
        }
      </script>
      <link
        rel="import"
        href="example1.html"
        onload="handleLoad(event)"
        onerror="handleError(event)"
      />
      <link
        rel="import"
        href="example2.html"
        onload="handleLoad(event)"
        onerror="handleError(event)"
      />
      <link
        rel="import"
        href="example3.html"
        onload="handleLoad(event)"
        onerror="handleError(event)"
      />
      <script>
        function importHtml(selector) {
          var content = document.querySelector(selector).import;
          var el = content.querySelector('.warning');
          document.body.appendChild(el.cloneNode(true));
        }
        
        importHtml('link[href="example1.html"]');
        importHtml('link[href="example2.html"]');
        importHtml('link[href="example3.html"]');
      </script>
    

Now let's compare the same feature with ES6 Modules and Templates using a
`helper.js` file.

    
    
      export async function importHtml(url) {
        try {
          let res = await fetch(url);
          let html = await res.text();
          let template = document.createElement('template');
          template.innerHTML = html;
          let el = template.content.querySelector('.warning');
          document.body.appendChild(el.cloneNode(true));
        } catch (e) {
          console.log(`Error fetching html: ${url}`);
        }
      }
    

Then we can import the modules on the page in a very clean way...no HTML
Imports spec here.

    
    
      <script type="module">
        import { importHtml } from './helper.js';
        importHtml('example1.html');
        importHtml('example2.html');
        importHtml('example3.html');
      </script>
    

My point is that you don't need HTML imports and you'll have to use JS even
with HTML imports so just use JS all the way :)

~~~
irrational
That seems like a lot of trouble to replicate the already built-in ability to
import external JS and CSS files.

------
ravenstine
I really hope that web components take off, because I'm getting pretty tired
of having to learn different ways of building components every damned year.
Most components don't need blazing-fast rendering engines, the templating
engine of the now, or even two-way bindings out of the box, and thus I'd like
to use components that can live on their own but also be easily wrapped into
whatever framework I'm using.

I'd like frameworks to be a lot closer to _scaffolds_ , or actually be
_frameworks_ , as opposed to what most of them are now which is
reimplementations of application units. The web components standard can help
make it possible for tools to become interoperable between frameworks(okay,
and _view libraries_ ), that would be wonderful.

~~~
nevir
Web components work very well in isolation, and/or within a homogenous web
component framework/library.

However, it is still pretty challenging to pass data throughout web components
(in a way that allows you to build a complete application). HTML attributes
are not great for data transfer (string serialization for everything). JS
properties are a bit opaque (not represented by markup). And everyone ends up
wanting some sort of property binding system, which may be unrealistic to
standardize.

I think there will always be a place for some amount of framework/library
support necessary for application builders.

~~~
spankalee
It's quite easy to pass properties between elements and build entire apps out
of Web Components. Many have been doing it for years.

Yes, it requires not just using plain markup - but template systems or
JSX+VDOM are really good at this, and there's a huge choice in libraries.
SkateJS is a library that allows you to plug-in several renderers to build
components. LitElement uses lit-html. Polymer, Svelte, Vue, and Angular (the
last when compiled to Custom Elements) have their own...

There also _is_ a chance at standardization with the Template Instantiation
proposal from Apple.

~~~
nevir
If it helps set context, I got my perspective as a developer on the Polymer
team

~~~
spankalee
Hi Ian, I know. :)

------
littlecranky67
WebComponents only solve the problem of creating independent, self-contained
functional units for the web. They don't fix all the other issues modern
framework stacks try to fix like state management, change detection, two-way
binding, inter-component communication/data passing etc. Thats why I don't see
the framework soup (Angular, React, Vue, Ember, Aurelia) going anywhere in the
near future. Maybe the "component" part will converge in the frameworks
towards WebComponents but all the other bits and pieces the framework stacks
ship will remain.

------
SEJeff
I believe Home Assistant's new fancy UI codenamed "lovelace" is based on web
components: [https://www.home-assistant.io/lovelace/](https://www.home-
assistant.io/lovelace/)

This should give you a sense of the power of web components.

------
option_greek
It's weird that the default behavior when appending a template is to not clone
it requiring an additional clone call

>>template.content.cloneNode(true)

~~~
lucideer
That's the default behaviour when appending a DocumentFragment or a Node, and
has been since 1997.

The template is just a container for the DocumentFragment, the template
content still behaves like any other DocumentFragment always would have, so
changing behaviour would be pretty crazy.

------
superbaconman
I'm not such a fan of how spread out everything is. I'd really like to see
html, js, and css all together in one place. React is the best I've seen, but
it doesn't provide a good solution for css.

~~~
spankalee
Check out LitElement. It lets you define everything in one place, and because
it uses Shadow DOM, CSS is handled as well.

Here's where we'll be with plain standard JavaScript once class fields and
decorators land:

    
    
        import {LitElement, html, property, customElement} from '@polymer/lit-element';
    
        @customElement('hello-element')
        class HelloElement extends LitElement {
    
          @property() name = 'World';
    
          render() {
            return html`
              <style>
                :host {
                  display: block;
                  background: blue;
                }
                h1 { 
                  color: white; // scoped to the ShadowRoot
                }
              </style>
              <h1>Hello ${this.name}!</h1>
            `;
          }
    
        }

------
ehnto
I put together a micro-pattern for working with WebComponents that I really
wish were cross browser compatible as it is. It works in Firefox and Chrome
and it is partly how I wish the web would move forward.

There is no technical limitations to making encapsulated portable pieces of
html, css and js, yet it seems a very uncommon practice to make libraries of
small re-usable components, even if they are boutique to you or your company.
I think that is partly down to how we go about specing out and producing
websites, and partly down to the fact that many don't realise you can already
do it.

[https://polylab.co/projects/polyblocks.html](https://polylab.co/projects/polyblocks.html)

An important part of that is well encapsulated CSS, and theming on top of
that, something I have written a little bit about as well.

[https://polylab.co/articles/ccm-contexts-and-components-
css....](https://polylab.co/articles/ccm-contexts-and-components-css.html)

------
robocat
caniuse shadow components:

[https://caniuse.com/#feat=shadowdomv1](https://caniuse.com/#feat=shadowdomv1)

So not Edge (I loath testing MSEdge - always finding new bugs in it -
yesterday the F12 development tools crashed even on a blank page -- needed an
opaque powershell script from MS to fix it...)

------
rado
Amazingly, Shadow DOM does not block all outside CSS. The * properties leak
in, unless you add #container { all: initial; } inside, but that doesn't work
in Firefox. I wonder why authors forget this strange fact.

~~~
spankalee
I don't think it's very strange. It's extremely likely that you want to
inherit the default inherited properties like color and font-family. Otherwise
Web Components would look out of place on the page by default.

------
ausjke
I could be totally wrong here as I am not an expert in frontend, it seems
Google has been the loner pushing web component(polymer,etc). Mozilla was
lukewarm about it. Something changed or did I miss something badly?

Vuejs has its own web-component(non-standardized), so does React. If browsers
can provide native web-component support that will be really nice.

~~~
e111077
I work at Google and can confirm that we are very much pushing web components
and Polymer / lit-html.

------
Flenser
Web components may give power to developers but they take it away from users.
Any page made with web components is hostile to user styling. I'm surprised
Mozilla would support them.

~~~
ravenstine
How many users apply their own style sheets? I remember this was popular among
a relatively few people, and now I don't know anyone who uses things like
Stylish or Greasemonkey/Tampermonkey anymore.

~~~
wwweston
User applied stylesheets are fairly uncommon, but then again, so is using a
screen reader. Both are essentially a kind of accessibility tech, and when it
comes to accessibility questions, the chief concern isn't necessarily whether
everyone uses it.

It's probably worth noting that reader-mode -- another accessibility tech --
does seem to be fairly popular.

~~~
someone7x
> and when it comes to accessibility questions, the chief concern isn't
> necessarily whether everyone uses it.

I wish more developers had your perspective.

My Dad uses Windows' high contrast mode. It's less that "literal dozens" use
this feature and more that this feature transforms all that desktop-shaped-
material into a computer for the vision impaired.

Isn't the biggest performance enhancement the transition from not-working to
working? I view accessibility as the ultimate performance enhancement for a
given slice of users.

~~~
TeMPOraL
Some companies care. Most don't. Unless a feature is used by double-digit
percentage of users, it'll be axed. It's a sad reality of today, and no, I
don't buy the arguments about saving development time, not when said by the
same people who also say they want to deliver value to users (as opposed to
extract value from them). Because somehow, feature cancellation always seems
to touch the features that enable users to unbreak things or optimize their
experience.

~~~
zeroname
Delivering value to only 0.1% of users is equal to taking away value from the
other 99.9% of users. You're not strictly saving development time, you're
reallocating it to better utility.

Now, if those 0.1% of users have some sort of legitimate accessibility issue,
we can talk about it. If they just have highly idiosyncratic preferences about
their user experience, the axe it shall be.

~~~
wwweston
I'm not sure 0.1% is an accurate reflection of the portion of users with some
accessibility issues.

Moreover, whatever the portion of users who currently have accessibility
issues is, the portion who _will_ have some is much much larger.

Finally: human accessibility _frequently_ seems to dovetail with machine
accessibility. Engineering done with accessibility in mind seems to be less
likely to result in silos and more likely to present an interface more
amenable to automated interaction.

