
Introducing Custom Elements - snake_case
https://webkit.org/blog/7027/introducing-custom-elements/
======
tannhaeuser
What's the point in introducing another syntactical feature to HTML (the
markup language) when you need Javascript for it anyway? When you're already
using Javascript, custom elements don't add any essential functionality.

Their inclusion as a feature into HTML feels like a not-so-well thought-out
decision from a language design PoV.

~~~
callahad
The combination of Custom Elements and Shadow DOM allow you to create a
separate, semantic representation of your markup that you can script against,
while encapsulating the actual markup required for presentation.

E.g., imagine you wanted to select all the images in a carousel. Without
Shadow DOM, something like document.querySelectorAll('.carousel img') might
pick up images being used as implementation details, like left/right button
images, in addition to the carousel images themselves. With Custom Elements
and Shadow DOM, your markup could contain only the content you intend to
represent, and document.querySelectorAll('.carousel img') would return just
the images being shown in the carousel.

Of course, like image carousels, whether or not this is a _good_ idea is
subjective. But it _does_ give you additional functionality. Hopefully we'll
learn how to use it responsibly.

~~~
dfabulich
Wait, what? You just described the benefits of Shadow DOM. Shadow DOM has
benefits, but you could get those benefits without Custom Elements, right?

What can I do with Custom Elements + Shadow DOM that I can't do with Shadow
DOM alone?

~~~
rictic
You can create reusable UI widgets that are usable without the user knowing
how they were written. e.g. with today's frameworks you need to know how to
create widget, and that may involve rolling up your sleeves and diving into a
bunch of framework-specific concepts. With custom elements you could just have
your server emit an <image-carousel> element, or do
document.createElement('image-carousel').

This is good for ease of use, but it's also great for interop. Custom elements
work with every way of writing a web site because every way of writing a web
site can deal with elements.

~~~
jessedhillon
But in reality, the server would have to emit

    
    
      <image-carousel delay="10" images="['...', '...']" end-behavior="cycle">
    
    

Thus making us no more free from the details of the component than we were
before.

~~~
abiox
> no more free from the details

i suppose it depends on what you mean by "the details."

details can be just the inputs required by "the interface" or it can be
specifics of "the implementation". the purpose of an interface is often to
distance (perhaps even "free", depending) the user from the implementation.

------
youdounderstand
Do custom elements allow re-templating?

It's pretty powerful to be able to separate the visual presentation of a
control (i.e., markup) from the logic. Every determinate progress bar has 0..1
progress and current progress properties, but the visual representation needs
to be able to vary widely in order for these elements to be truly reusable.
And it would be nice to be able to change the template (including
adding/removing DOM elements to it) without having to define a subclass in JS.

~~~
spankalee
Custom Elements don't specify how they render at all - they're only about
creating instance of specific HTMLElement subclasses during browser operations
like parsing, document.creatElement(), cloneNode(), etc., and firing
"reactions" like connectedCallback() and attributeChangedCallback(). Once
created, Custom Elements can really do anything to the document, there's not
built-in concept of templating.

Generally though, Custom Elements are going to create a shadow root and render
some DOM into it. It's all just code, so an element subclass can use a
template library, and can do things like you want, like decouple its template
from its implementation.

Here's a sketch of an element that would use a template as determined by a
'template' attribute.

    
    
        class MyElement extends HTMLElement {
          constructor() {
            super();
            this.attachShadow({mode: 'open'});
          }
    
          render() {
            this.template.render(this.shadowRoot);
          }
    
          attributeChangedCallback(name, oldValue, newValue) {
            if (name === 'template') {
              this.template = templateLib.lookup(newValue);
              this.render();
            }
          }
        }
    

And you'd use it like this:

    
    
        <my-element template="progress-bar"><my-element>

------
deadA1ias
How do we employ progressive enhancement using custom elements? Given their
reliance on JavaScript, as an old-school front-end developer, this feels like
an unfortunate oversight.

~~~
jannotti
I don't see how this could possibly work even a little bit without Javascript.
What would you fall back to? A static hunk of HTML? That could only work in
the very specific case of a custom control that happens to have exactly the
same utility on the page as an existing HTML element. And even then, you'd
need to add a templating language, so you could express how to render that
HTML chunk with a certain value or text. This templating language would not be
Javascript, since you're trying to avoid that. So we add a new templating
language to HTML for the benefit of rendering content for people who turn off
Javascript?

~~~
deadA1ias
I completely agree, but the question remains what experience do we provide
when JavaScript is not available? (Progressive enhancement isn't just for
"people who turn off JavaScript", it's an defensive approach to providing
inclusive, universal solutions on the web. Something I feel is lacking in the
modern, front-end developer's worldview.)

~~~
Touche
How would you do a progress bar without JavaScript? Well, you wouldn't. So
custom elements don't affect progressive enhancement as far as I can see. They
enhance the DOM when JavaScript is available and when its not they are
essential a div.

~~~
dsego
Why isn't there a skinnable native progress-bar widget?

------
c-smile
All this is over-engineered IMO.

It is just enough to add support of behavior property to CSS:

    
    
          my-toggler {
             display:block;
             behavior: MyToggler url(my-components.js);
          }
    

As soon as browser will see <my-toggler /> in markup it will call function
MyToggler() with 'this' set to the element in file my-components.js. That's
what I did in my Sciter[1]. It was proven as quite useful and easily
understandable yet implementable in 100 lines or so of native code.

The value of shadow DOM is also quite doubtful to be honest. It is shadowed
from whom and for what purpose? User don't care about DOM structure ...
Programmers? They are OK with that.

[1] [http://sciter.com](http://sciter.com)

~~~
timothya
> _All this is over-engineered IMO._

It's complicated in order to provide a lower-level API so that libraries can
take advantage of different features and provide more opinionated ways of
creating custom elements. Polymer is an example of a library which provides a
simpler (but slightly more opinionated) API on top of custom elements.

> _The value of shadow DOM is also quite doubtful to be honest. It is shadowed
> from whom and for what purpose? User don 't care about DOM structure ...
> Programmers? They are OK with that._

The Shadow DOM provides style isolation, which is convenient to developers
mixing-and-matching components, and can also be a performance boost as
browsers can optimize for the fact that styles don't cross the shadow
boundary. It also provides a bit more isolation for when you are writing code
to discourage components from reaching into each others' private
implementation.

~~~
c-smile
_> The Shadow DOM provides style isolation ..._

I've proposed once @ www-styles concept of style sets: the @set construct.

Style sets mechanism solves two principal problems of CSS:

1\. They allow to define local and independent style systems for elements in
the same DOM tree.

2\. Style sets allow to reduce computational complexity of style resolution.
In classic CSS all style rules that used by the document are placed in the
single ordered table. Task of finding list of matching selectors for the
element has computational complexity near O(n), where n is a number of rules
in the table. And style resolution of the whole DOM tree is O(n * m * d) task.
Where m is a number of DOM elements and d is an average depth of the tree.
Style sets allow to reduce significantly n multiplier in this formula.

[http://sciter.com/css-extensions-in-h-smile-engine-part-i-
st...](http://sciter.com/css-extensions-in-h-smile-engine-part-i-style-sets/)

 _> to provide a lower-level API ..._

I haven't seen any requests from framework/platform developers.

In contrary, the feature to call particular function when particular element
appears in the DOM was actual from the time of first framework appearance.
People were trying to solve it with DOM mutation events but they did not go
through - too expensive, etc.

------
mrdoob2
Some custom elements I worked on this week: [https://mrdoob.github.io/model-
tag/](https://mrdoob.github.io/model-tag/)

~~~
dsego
Not supported in Safari, on Chrome (MacOS) I get model-gltf.js:19758
THREE.WebGLRenderer: Error creating WebGL context, and a bunch of other
errors.

------
Mackiovello
What's the difference between this and Polymer?

It seems to be somewhat similar.

~~~
Fifer82
I have the same question, and where does either fit into the other bits and
pieces like Angular and React?

~~~
Mackiovello
Exactly! It would be interesting to hear what the creators had in mind when
they built this.

~~~
tdumitrescu
Maybe it's not obvious from the WebKit article: Custom Elements aren't new,
their native implementation in WebKit is what's being announced here. Custom
Elements are part of the Web Components collection of cross-browser standards
introduced in 2011 (and still not finalized). React was in its infancy at the
time, Angular was just getting off the ground. Polymer has always been built
on top of the Web Components standard(s). This post isn't about "Yet another
new framework competitor!"

------
captn3m0
What is the state of Blink getting upstream webkit changes? How much time
would this take to land in Chrome development?

~~~
pier25
Blink doesn't get any upstream changes AFAIK. In fact it's moving much faster
than WebKit and got custom elements back in 2014 with version 33.

[http://caniuse.com/#search=custom%20elements](http://caniuse.com/#search=custom%20elements)

------
zengid
Wow, since I went back to school recently I've lost touch with the HTML/JS
news, so I've been completely unaware of browsers starting to integrate these
features. Will this mean less dependence on React in the near future, or am I
missing something?

------
nitwit005
I guess this is more of a shadow dom question, but what's the efficiency of
the CSS with this pattern? It seems like styling is being inserted into every
instance. Is there a browser feature to avoid internally duplicating it?

~~~
spankalee
Chrome internally dedupes <style> tags with identical text, and typically the
style tag is generated by cloning an existing one from a template, so there's
very little actual overhead here.

~~~
nitwit005
Makes sense. Thanks.

------
thewhitetulip
I am very excited about this! I recently got re-introduced to the Polymer
project. What they are doing is definitely the future of front end dev.

------
ilaksh
Not in MS Edge because it makes the browser more competitive with MS software
frameworks that have had similar features for decades.

~~~
pax_americana
All four features of the Web Components Spec (Shadow DOM, Custom Elements,
HTML Import and Template Element) are the top most requested features in the
MSEdge Developer Uservoice. <template> has already been implemented while the
remaining three are on their backlog.

[https://wpdev.uservoice.com/forums/257854-microsoft-edge-
dev...](https://wpdev.uservoice.com/forums/257854-microsoft-edge-
developer/filters/top)

------
Too
What happened with separating content and presentation. I thought everybody
got over the jquery madness and went on with template based frameworks like
react and angular. Who would write code like this in 2016?

    
    
        this._label = shadowRoot.querySelector('.label');
        this._label.textContent = newPercentage + '%';

~~~
greenyouse
This looks like it's for the custom elements part of the web components spec.
Doing HTML templates is already supported in most browsers [0]. I think they
were just trying to show how to create custom HTML tags and left out other
parts because it would be outside the scope of the article.

webcomponents.org has tons more info about web components.

I think it's pretty awesome to get templating, custom elements, scoped
styling, and HTML imports as a browser feature without JS frameworks. It'll be
neat to have as an option in the future when browser support gets better and
people start using it.

[0][http://caniuse.com/#feat=template](http://caniuse.com/#feat=template)

~~~
Too
Html <template> doesn't do data binding as far as I can see? It's just a way
to reinstantiate fragments of a page and then you are back to selectors and
setting properties with js. When I say templates I mean declaratively defining
the page with data binding in the html so the javascript code doesn't have to
know anything about the html.

There are two major reasons to use angular/react: rendering with data binding
and reusable components. If web components is going to be a feasible
replacement it has to both, when looking at it now it seems as it only does
the component-part. Otherwise we will just end up with tons of web components
that pull in angular as a dependency and we are back on square one. In fact it
will probably be worse than before because it's so easy to use third party web
components that you will not even think about all the different dependencies
they pull in and at the end of the day your page will require doenload of both
angular, jquery, react, polymer and vue. This is one step forward and two
steps back. Unless web components can significantly improve the performance
and code size of all these existing frameworks under the hood.

------
slim
New elements? That's what XHTML does since 1999

~~~
om2
XHTML doesn't give you a way to automatically give behavior and composite
structure to a new element. It just gives you a way to put one in your markup
without the validator complaining. But it won't do anything by default.

------
Retr0spectrum
What will this actually be useful for?

~~~
achairapart
A dependency-less, component-based alternative to React.

It's part of Web Components:
[http://webcomponents.org](http://webcomponents.org)

~~~
untog
_Parts of React_. For me the state management is a core part of React, and as
far as I can tell this doesn't cover that, just the rendering part.

~~~
jannotti
This seems almost exactly like all of React. These components do have state,
just like a React component. If you're talking about how the state is changed,
then now you're not talking about React. You're talking about redux, flex,
etc. You may very well want something like that here too, but that's not
because this isn't like React, it's because it _is_ like React.

~~~
mambodog
Where's the part of React which allows me to return a new copy of what I want
the HTML to look like, while only updating the changed elements of my view
instead of totally blowing away the existing elements (the virtual DOM +
reconcilitation part of React)? Also, where's the declarative event binding
part?

I'd also point out that the state tree (setState) _is_ a part of React, and
plenty of apps are just fine being built using only setState for state
management (no redux/flux/mobx).

~~~
Touche
You're right, custom elements don't do that, and it's not a goal of the custom
elements spec (as far as I can tell) to promote any particular programming
style. It's a low level spec. So showing the most low-level way to use it
makes sense.

Here's a library that combines custom elements with VDOM rendering:
[https://github.com/skatejs/skatejs](https://github.com/skatejs/skatejs)

------
pomber
Great news, only thing missing now is HTML imports

------
drivingmenuts
This is a great idea, but how do you get around the fact that it's not valid
HTML? Is that even a concern anymore?

~~~
mediumdeviation
Custom HTML tags _are_ valid HTML. Note the requirements for custom tags to
always include a '-' in their names. This distinguishes custom tags from
native ones. [https://html.spec.whatwg.org/#valid-custom-element-
name](https://html.spec.whatwg.org/#valid-custom-element-name)

~~~
kuschku
Will the browser be able to display them without requiring JS?

If no, then it can't really be argued to be valid HTML by itself.

~~~
ohyoutravel
Yes, the article specifically states this.

~~~
demircancelebi
The article says "without relying on a JS framework.", which is different than
not requiring JS. It does not work when Javascript is disabled.

