TL;DR Here is a repository with a working example. :)
This week the Polymer project announced their 2.0 release candidate, which uses the new (ES2015) class based spec of custom elements v1.
That post made me think about the future of component based development on the Web in general.
CSS & HTML Framework Based Components
I've seen many projects created by using a CSS framework like Bootstrap. The idea is simple, the frameworks define reusable components, which are independent from the rest of the application. This is accomplished by using HTML and CSS as an interface.
At the top of your app, you include the Bootstrap CSS and at the bottom of your app, you have to use the classes in your generated HTML to render a component.
For example, a progress bar component in Bootstrap:
// Use
<div class="progress">
<div class="progress-bar" style="width: 60%;"></div>
</div>
As you can see, in consists of two <div>s and they need specific CSS-classes and style. To replicate the behavior you need HTML and CSS.
Now, because every JavaScript framework lets you generate HTML and CSS, you can use the progress bar independent from this framework. Create a whole app in Ember with help of HTMLBars templating language and later rewrite the whole thing in React with JSX. Different JavaScript based technologies, but they both interface with HTML and CSS.
The problem is, you still have to write the correctly nested HTML and sprinkle it with the right CSS classes.
JavaScript Framework Based Components
Component based JavaScript frameworks like React already solve that problem.
For example, the progress bar written as React component:
// Define
function ProgressBar(props) {
return (
<div className="progress">
<div className="progress-bar" style={{width: props.complete}}></div>
</div>
);
}
// Use
<ProgressBar complete="60%" />
Now you can use the progress bar in your app without worrying about the HTML or CSS structure. If Bootstrap changes its classes or its HTML later, you can simply go to your React component and change it there.
But!
It's a React specific solution and your have to maintain your own implementation.
Wouldn't it be nice, if Bootstrap simply provided you with such a component, usable in your obscure framework of choice?
Custom Elements to the rescue!
Custom Elements Based Components
Web components, a set of specs for framework-less components, tries to get you out of this mess by providing a W3C spec for creating such components. It's basically a browser API for creating your own HTML elements.
This adds the missing bottom to CSS and HTML based frameworks like Bootstrap, which define CSS classes at the top and require you to add them to your correctly structured HTML in all the right places.
They could provide you with an HTML element, that specifies its whole interface via HTML attributes, like Reacts components do via props. If they want to change the implementation, they had access to the CSS at the top and the HTML at the bottom.
For example, the progress bar written as React component:
// Define
class BootstrapProgress extends HTMLElement {
connectedCallback() {
const progressBar = document.createElement("div");
progressBar.className = "progress-bar";
progressBar.style = "width: " + this.getAttribute("data-complete");
const progress = document.createElement("div");
progress.className = "progress";
progress.appendChild(progressBar);
this.appendChild(progress);
}
}
customElements.define("bootstrap-progress", BootstrapProgress);
// Use
<bootstrap-progress data-complete="20%" />
This component is based on browser internal APIs. Since it defines a regular HTML element, it can be used in all frameworks that can create DOM elements.
Conclusion
Custom Elements are a nice way to encapsulate UI components that make up your application.
Sadly, Custom Elements aren't implemented in all major browsers yet. Firefox is still implementing and Edge hasn't even started and you can't blame them. As the Custom Element spec says:
This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
But, thanks to the magic of polyfills, you can use Custom Elements even in non-conforming browsers.
Top comments (3)
Can't blame them because it's a draft? That's misleading IMO. Implementations are one of the critical qualifications for drafts to become recommendations. Vendors can't wait for proposed recommendation status to start implementing. If they did, nothing would become a proposed recommendation. If something is still a working draft, it means it's not widely enough reviewed--something in which Microsoft also must participate.
Which is not to say they haven't, although I perceive Apple, Mozilla, and Google as having been more active and vocal on web components.
Awesome intro to what they are and how they bring an improvement to traditional CSS frameworks!
Take a look at github.com/Wildhoney/Switzerland for a more functional implementation and alternative to Polymer.
Here is some code for Bootstrap: dgt41.github.io/bs4-custom-elements/
Still WIP...