Web Components is the umbrella term for a collection of independent but closely related features being added by the W3C to the HTML and DOM specifications to facilitate developing first class web components using standard browser features. Those features are:
All these features have been around for sometime, have been though several design iterations, and have differing browser support. This post outlines each in turn with brief examples and links to further documentation to help you understand the fundamentals of Web Components. We’ll build an example as we go.
Polyfills are available for all of these features so you can use Web Components even in the browsers that don’t natively support them.
HTML Templates enable you to create DOM elements that are not part of the main document. They exist as fully formed DOM elements but exist in isolation, and no resources referenced (images, scripts) will be downloaded or run until you want to insert the template into the document. Once inserted they become part of the document and behave in the same way as any other DOM element.
HTML Templates are the most mature of the Web Components features and are supported in all the evergreen browsers. See MDN for more information.
HTML Imports are a way of importing HTML into another HTML page. When you think about it, it seems crazy that there hasn’t ever been a standard way to do this. There are ways to do it without HTML Imports, but none of them are particularly elegant or easy to use. With HTML Imports you reference an HTML file in much the same way as you would a CSS file but using ref="import" rather than ref="stylesheet". The HTML Import can include any valid elements a regular HTML page body would have, including scripts, and are cached by the browser in the same way as any other resource.
At first glance this functionality seems similar to HTML Templates, just with the HTML in a separate file. The key difference is the handling of scripts. As mentioned before, scripts referenced from an HTML Template are not downloaded or run until the DOM is inserted into the main document, whereas scripts in an HTML Import are downloaded and run as they are encountered. The benefit of this is that you can import a HTML document that initialises itself so you don’t need to know about its inner workings to start using it straight away. It’s entire lifecycle can be managed independently from the document it is imported into. Of course you can have the best of both worlds - you can use HTML Templates within HTML Imports depending on your needs. Furthermore the content of imports, including scripts, will only ever run once no matter how many times the import is referenced, so you don’t need to worry about including the same import in multiple places.
Custom Elements are often taken as the key feature of Web Components, and the two terms are often used interchangeably. Custom Elements are a way of extending the DOM to include new first class elements. Consider the basic building blocks of HTML - native elements such as divs, headings, forms, inputs, buttons and so on - they have a clearly defined meaning and a common standard API.
The main disadvantages to that approach are that the new Frankenstein element has no clear semantic meaning, and you are introducing a performance cost in order to manage the lifecycle, behaviours and events of the element in a non standard way. You are also tying yourself into a particular implementation that will likely not be compatible with other implementations. Custom Elements on the other hand have built in browser support for all those things so they can leverage the performance advantages that go with it, as well as not being dependent on any particular 3rd party implementation.
Custom Elements allow you to create new DOM elements which have their own tag names and can make direct use of the same DOM APIs as native elements do. They can be imported into any document and used wherever native elements can be, including any current (or future) libraries and frameworks. Best of all they are composable - you can use custom elements within custom elements within custom elements to build anything from simple presentation elements to whole applications. Custom Elements have both a declarative interface (using attributes) and an imperative one (using properties).
Custom Elements have wide browser support but be sure to look for guides and documentation to v1, not the previous v0 incarnation as they differ considerably. The Web Fundamentals site has a great v1 guide on Custom Elements.
The Shadow DOM solves this by isolating your Custom Element’s DOM from the rest of the document. You can use any classes or IDs you like without worrying about using unique values from the rest of the document. The CSS inside the Shadow DOM is also scoped to the element so it will only act on the content of the element itself, and conversely styles outside of the element will not be applied to the element contents. Finally the Shadow DOM allows you to specify which styles can be overriden from outside the element (using CSS variables and mixins) so you can create customiseable elements if necessary. You can also optionally include and style elements that are within your Custom Element’s opening and closing tags (referred to as the light DOM) using slots.
Shadow DOM has wide browser support but be sure to look for guides and documentation to v1, not the previous v0 incarnation as they differ considerably. Again, the Web Fundamentals site has a great v1 guide on Shadow DOM.