A look at Web Components

No Comments

When it comes to modern web applications, there is currently (almost) no way around Angular and React. Of course there are very interesting alternatives such as Vue.js, Ember etc., but in larger projects, they played a considerably smaller role in 2017.
Obviously, the question arises as to how things will develop in the fast-moving ecosystem around JavaScript etc. in the upcoming years. Certainly, component-based frameworks will continue dominate the market in 2018 and beyond. However, an alternative has been emerging on the horizon for some time now: Web Components.

Web Components are a series of features that the W3C is currently adding to the HTML and DOM specifications. Web Components allow you to create reusable components for Web applications, a concept already familiar from Angular and React.

In this post we will take a look at these features and the possibilities they offer.

Example with React

Let’s take as an example a list of strings we want to display. In React it looks like this:

This feels a lot like “native” HTML. While React only allows you to use your own components, Web Components allow you to define your own HTML elements, which you can integrate into a page like normal HTML. Therefore, they can also be easily used on the server side. Another advantage: they behave like HTML and can therefore be used with any JavaScript library and any framework that can handle HTML (e.g. for events).

Web Components are also based on Web standards and are therefore more future-proof. However, we must also take into account one disadvantage that Web Components unfortunately currently have: they are not yet available in every browser without difficulty. However, this functionality can be added using Polyfills.

Polyfills

Polyfills allow you to retrofit functions that are not currently supported in the browser. This in turn can mean that the performance does not correspond to the native implementation and is an additional burden for the user, since the respective script must be loaded and executed.

Overview

When we talk about Web Components, we refer to four features that we will explore in more detail below:

  • HTML Templates: a way to store HTML templates in the document using the <template> element. These can then be manipulated with the help of JavaScript.
  • HTML Imports: possibility to load HTML into other documents
  • Shadow DOM: create your own, independent DOM within HTML elements
  • Custom Elements: API to write your own HTML elements

    In the following we will look at these features. The corresponding code is also on GitHub or can be inserted into an HTML file to see the result in the browser.

    HTML Template tag

    With the template element, we can create templates in HTML, which we can manipulate and use via JavaScript. The template element is parsed by the HTML browser and included in the DOM tree, but not rendered on the page.

    First we need a template which we can insert into our HTML file at any place.

    In this case it is only a li-element, which we want to include in a list. For this we need an empty list in the same HTML file:

    As to JavaScript: since Web Components are still under development, we first check whether HTML templates are supported in the current browser (1). Here we check if you could create a template element which has the property content, otherwise we insert a text informing us about the missing support (2). This technique is called progressive enhancement and is intended to ensure that as many users as possible can use a page.

    If we can use HTML templates, we define a list of strings we want to see as li elements in the list. Then we access the template (1) via the DOM API and look for the li element (2) within the template. We need the list to insert the generated li elements (3).

    Then we iterate over the previously defined features and write the respective feature into our li element (4), clone the whole thing (5) and insert the clone into the list (6).

    Interim Conclusion: Template tags

    If we look at HTML template tags themselves, they are not very spectacular: nothing you weren’t able to do before with a few lines of JavaScript in a similar form. They probably inflate the HTML code and offer little added value. What’s new is the element template, which we can use in HTML and then manipulate via JavaScript. Nevertheless, we should not write them off directly: we’ll see later that we can use them in combination with the other features.

    Currently, Chrome, Edge, Firefox and Safari support HTML Templates. Internet Explorer lacks support. Altogether 89% of users support HTML templates.

    ChromeFirefoxSafariEdge
    yesyesyesyes

    HTML imports

    The idea behind HTML Imports is to outsource HTML code and load it into the application using the link element.

    First we need an HTML file containing the code to import.

    In our actual page we only have to reference the file to be imported via a link element.

    In the JavaScript code we can now check again whether the current browser supports HTML imports:

    Now we can load the content of the import via JavaScript (1), search for the element from the import we would like to use (2) and insert it into our HTML file (here directly in the body element) (3).

    Interim conclusion: HTML imports

    Of course, similar to the previous example, we can manipulate the HTML (but that would be nothing new). HTML imports remove the additional template tags in our document and create a smaller HTML file. In addition, outsourcing allows for reuse in other files. Unfortunately, this feature is not free, as we now have an additional server request for each import. This means that we have to consider things like caching and CORS.

    HTML imports are currently only implemented in Chrome and therefore available to about 68% of users. Mozilla is currently not planning to implement HTML imports.

    ChromeFirefoxSafariEdge
    yesnot plannednot plannedin discussion

    Shadow DOM

    The shadow DOM lets us implement our own DOM within HTML elements and store additional HTML components including styling, for example. The Shadow DOM is independent of the DOM, which simplifies the development of components enormously. Especially the styling is simplified, because CSS rules do not influence each other.

    Our HTML is a bit simpler here: we only need one element into which we insert our shadow DOM. This is reminiscent of the established frameworks, which also only need one entry point. The p element below the div serves as an example of styling within the shadow DOM.

    As with the other examples, we need to check if we can use the Shadow DOM in the current browser.

    Now we can select the element in which we want to create the shadow DOM and create our shadow DOM with attachShadow() (1). With mode: “open” (2) the Shadow DOM can be manipulated by other JavaScript functions. If mode: “closed” is used here, this is not possible. A simple use case is e.g. to write additional HTML into our shadow DOM with the help of innerHTML (3). This does not work for all elements, so instead of a list here we insert a few paragraphs into the shadow DOM. The CSS, which is also added (4), only affects the elements in the shadow DOM.

    Interim conclusion: Shadow DOM

    This is a very basic example for the Shadow DOM. It is great that you can create your own DOM with relatively little code and dynamically add HTML code, which can be styled independently. However, the original HTML code does not reflect these changes and thus at first glance it is not obvious where the contents of the page come from.

    The Shadow DOM is currently fully implemented in Chrome and (the next) Firefox. It is partially implemented in Safari, so that about 79% of users can use the feature.

    ChromeFirefoxSafariEdge
    yesin development (next version)partialin discussion

    Custom elements

    Custom elements allow you to write your own HTML tags and use them directly in the HTML document.

    In the most basic case it could look like this, where we first include our custom element in the HTML code:

    To check whether we can use custom elements, the following check is available:

    Now we can create a JavaScript class (this inherits from HTMLElement) (1) and use innerHTML (2) to define what the markup of the component looks like. Important: the super constructor must be called for everything to work.

    At the end we register our component as <web-components> (3). Custom elements must have a dash (-) in their name to work.

    The methods that we can use in a custom element are noteworthy.

    APIBeschreibung
    static get observedAttributes()function that returns an array of attributes to be monitored.
    connectedCallback()this function is always called when this element is inserted into the DOM.
    disconnectedCallback()this function is always called when this element is removed from the DOM.
    attributeChangedCallback(attrName, oldVal, newVal)Called when one of the monitored attributes is changed (for example, by an event).
    adoptedCallback()is called when the element is moved to another DOM.

    Interim conclusion: Custom elements

    Since we use custom elements in our application directly in HTML code, we can integrate them more easily than React and Co. Browser compatibility, however, is a problem without Polyfill.

    Custom elements are partially implemented in Chrome and Safari, resulting in a distribution of about 79%.

    ChromeFirefoxSafariEdge
    yesin development (next version)yesin discussion

    Shadow DOM, HTML Templates und Custom Elements

    The previous examples show how each feature works. Only the combination of the individual features makes Web Components possible: We create a template (1) and use this via a shadow DOM (2) in our custom element (3).

    Conclusion

    In summary it can be said that the technologies presented here cannot yet be used in the project without using Polyfills. With almost 70% distribution, however, a good part of the market is already covered. As soon as the browser manufacturers follow suit, nothing should stand in the way of using them.

    The features presented here are low-level APIs, which can only serve as a foundation for other frameworks and libraries. It is conceivable that React will eventually switch to Web Components, or, as Vue.js and Angular already do today, offer libraries with which Web Components can be created (vue-web-component-wrapper, angular elements). Promising frameworks such as stencil.js or Polymer, which simplify the use of Web Components, are also available.

    The code examples are also available on auf GitHub.

Daniel Mies

Daniel is part of the codecentric team as a Software Crafter since 2015. He likes to work in backend as well as in the frontend.

Currently his focus lies on IoT and Industry4.0 where he supports companies as product owner in their projects.

Comment

Your email address will not be published. Required fields are marked *