Getting Started with Web Components

Working at Mozilla has let me get in on the ground level of many upcoming specs, and one of my favorites is the Web Components spec. Haven’t heard of it? I don’t blame you, it’s been relatively silent in the general web development community, but in my time contributing to x-tag, I’ve gotten more and more excited about Web Components. This post aims to bring you up to speed on the basics of Web Components, or custom elements, and gives you a launching point to creating your own HTML elements!

What are Web Components, and Why?

We cannot continue creating dynamic web applications by simply using the elements we’ve been given. That simply wont work. Our desktop and mobile applications are advancing so quickly that standards bodies and browser vendors alike have recognized that placing custom elements into the hands of users is much more flexible and much more sustainable. If you can create your own custom HTML elements, you can solve all of your own markup problems.

document.registerElement and Creating Custom Elements

The Web Components spec calls for an added document.registerElement method which allows developers to define their own elements. Detecting support for custom element creation is simple:

if('registerElement' in document) {
    // Yay, custom elements are supported natively!
}

If the document.registerElement method isn’t available natively in the browser, an excellent polyfill is available by the Polymer project. Polymer’s registerElement polyfill will allow you to create custom elements to spec.

So how can you create your first basic custom element? It’s as easy as a call to document.registerElement:

document.registerElement('slide-show');

This JavaScript generates:

<slide-show></slide-show>

It’s that simple to create your own HTML elements! This custom element, however, doesn’t take advantage of all this new API has to offer. Let’s see what else we can do!

prototype and extend

Naming elements more semantically is nice but not very powerful. The first way to add power to a custom element is to provide it a prototype to work from. Starting with a base HTMLElement, we can provide more default methods on the custom element:

//  Create the new element prototype
var slideshowPrototype = Object.create(HTMLElement.prototype);
slideshowPrototype.next = function() {
    // Code which will move to the next item in the slideshow
};
slideshowPrototype.previous = function() {
    // Code which will move to the previous item in the slideshow
};

// Register our slideshow element with its default prototype
document.registerElement('slide-show', {
    prototype: slideshowPrototype
});

Any instance of a <slide-show> element will have next and previous methods, and any other methods you add to its prototype.

To further empower the DOM, we can also extend existing elements. The first step is adding an extends key->value when registering our custom element:

// Register our slideshow element with its default prototype and extending an existing element
document.registerElement('slide-show', {
    prototype: slideshowPrototype,
    extends: 'div'
});

With this extension in place, you can use an is attribute on an existing element to usage the element with said extension:

<div is="slide-show">
    <!-- slideshow body -->
</div>

This DIV now answers to the slideshow prototype API — hooray for super powerful elements!

Lifecycle Callbacks

If you’re a fan of callbacks (and who isn’t), the web components API provides a few very useful callbacks which you can add to the element’s prototype:

  • createdCallback – fires when an instance of the element is created.
  • attachedCallback – fires when injected into the document
  • detachedCallback – fires when removed from the document
  • attributeChangedCallback – fires when an attribute is added, removed, or changed.

These callbacks are incredibly useful when creating and managing custom elements. There are shims available to implement these on native elements but a proper API for doing so is exactly what we need.

x-tag Custom Element Library

Now that we have the custom element capability, we can start building awesome components. One component library building momentum comes from Mozilla, and it’s called x-tag. x-tag provides an excellent set of frequently-used functionality wrapped in custom elements, including:

  • Calendar
  • Tooltip
  • Flipbox
  • Slidebox
  • … and many, many more

The x-tag documentation is second to none in explaining its all-encompassing API, as well as keeping developers up to date as to the current status of web components and their usage. x-tag is very well tried and tested so I consider this the best resource for creating web components.

Finding More Web Components

Web components are very much like plugins to a JavaScript library, except that in this case, the library is the native HTML platform itself. There are a few notable sources of pre-built, useful web components:

Brick

Brick is another collection of web components from Mozilla. Brick is under very heavy and active development and features components which may be implemented in Firefox OS’ native interfaces. Brick is very much focused on providing mobile-ready HTML5 components, so you can be assured they’ll work for all devices.

CustomElements.io

The CustomElements.io websites provides, at present, over 100 freely available, high quality web components from a variety of authors. Before coding a custom web component for yourself, be sure to check out this site!

Styling Custom Elements

There’s been confusion over how styling custom elements is done, and the good news is that you style custom elements as you would any other native element:

slide-show {
    display: block;
    position: relative;
    /* more */
}

slide-show div {
    /* styles */
}

Style away as you’d like!

<conclusion>

The days of simply using the elements we’ve been given will soon be coming to an end. The future of web app development will feature intelligently named, more intelligently coded web components. Web components will allow for more control over element behavior and more closely coupled element collections and events!

Comments 0

Leave a Reply