My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Sunday, August 17, 2014

Self contained Custom Elements via restyle()

There is an ongoing discussion about import link for both dependencies and Web Components, here my quick take on it: drop them! Just trash the fluff and use the DOM, it's freaking awesome these days and it works in every browser, you will rarely regret this choice!

However ...

Some dependency could be given for granted, which is actually the best we could do in order to simplify the mess (i.e. you use jQuery all over, don't include it in your file, assume it's there and mark it explicitly as must have in your component documentation).
Be sure that polyfills and/or dependencies are loaded upfront, which also means you should forget about async and other tricks if you want to rely these libraries are in.

restyle() and Custom Elements

Assuming this tiny library is in place, slightly more than just 1KB once minified and gzipped in its latest version, you might end up being able to confine the entire custom element behavior in just a javascript file. Have a look at this demo, based on same CSS and mostly same JS used in this post.
Yes, you got it right, custom elements are entirely confined in a single JS file.

A little helper for huge results!

The changes I've made in restyle are basically components oriented so that it's now possible to automatically confine some CSS inside a rule:
var style = restyle('my-element', {
  div: {
    border: '1px solid black'
  i: {display: 'none'}

// will result in 
my-element div {
  border: 1px solid black;
my-element i {
  display: none;
Having somehow "sandboxed" all nodes also simplify the concept behind any Shadow Dom, except it works today with all browsers compatible with my document.registerElement and restyle code, basically all browsers you can think of except IE8 due Custom Element limits in this browser.

As Summary

Using little tools like restyle could give us the opportunity to use today Custom Elements without needing to wait a universally good, fast, and reliable solution via HTML5 imports combined with ES6 too, we can already place in a semantically similar way CSS into JS thanks to restyle and via JS also solve dependencies when appropriate. Feel free to play with the freshly new version of restyle and please don't hesitate to file bugs or suggest improvements: these are early days for Custom Elements and Web Components, this is the right time to nail it right!


Peter said...

Thanks for sharing! And is there any data binding (one or two-way) solution you can recommend to use in this environment?

Andrea Giammarchi said...

Hi Peter. I am not sure I am answering your question but `attributeChangedCallback` is a special Custom Elements method that is triggered every time an attribute changes in the DOM element.

Together with `addEventListener` you could keep updated any model you want + you could do the same knowing all properties you want to watch with a generic object, using either a Proxy or a list of getters/setters.

Hope this helps