Let’s Make a Web Component!

So Web Components – they’re hot like the centre of mince pies! Bet you want to take off the top, let the middle cool a bit, add some cream and start eating, right?

I know I do.

You may remember last year, when I wanted you to turn your phone off, close your twitter client, ignore your emails and take a couple of hours just for yourself. Well that time of year has come around again! So let’s do it, let’s make a Web Component :D

I’m pretty sure you’ve probably read about them this year, there’s also a big chance you’ve seen someone do a talk about them, (if you haven’t I highly recommend this wonderful talk by Peter Gasston), don’t worry if you haven’t though, I will do my best to explain each part as we go along – just so we’re all on the same page.

It worth noting this is an introduction, just a quick tutorial to give you a head start on all the shenanigans involved in Web Components. At the time of writing these examples only work in the latest version of Chrome (v31), I recommend caniuse.com for the latest and greatest browser support info.

You can find all the examples in this article here and all the code for them here.

So what is a Web Component. Well it’s a sort of sandboxed, reusable DOM structure. There are quite a few standards that go into making one. Take the logo for instance. Wouldn’t it be nice if that was interactive. It could be a working navigation for this site, you could hover and it could animate. Wouldn’t it be nice if you could hide away any crazy mark up you create for styling such a logo, if you could give the element a semantic name and wouldn’t it be nice if you could hand it all over for someone else to drop into their site, one component with it’s own HTML, CSS & JavaScript, which didn’t interrupt any of their existing code?

It would be very nice and entirely possible with all the standards that make up Web Components.

So let us start with the first nice thing. Let’s mark up and style that logo:

Templates

Templates are the first thing we should look at when trying to create a Web Component. To quote the working draft:

The <template> element contains markup intended to be used later.

You can put markup (or content) encapsulated by the <template> tags anywhere in an HTML document. The content is parsed but is inert. Images aren’t downloaded, scripts aren’t passed etc… Pretty handy if we want to create a reusable/cloneable bit of markup.

All we’ve done here is taken the content out of the template, #twelve-devs-logo, and stuck it into an empty div #show-content, on the page to be rendered. Easy, but dare I say it handy.

Enter the Shadow Dom.

Hopefully you’ve got Chrome open by now. Go on inspect this audio element:

Can’t see anything but an empty audio tag right? Where is that play button, scrubber, volume control and time? It’s gotta be there somewhere…

Click on the cog icon to the bottom right of the dev tools. Under the Elements sub heading there is ‘Show Shadow DOM’ checkbox, select this and then close the Settings panel. Back in the dev tools you should now be able to expand the audio element. Keep expanding and a world of divs and inputs suddenly appear before you. All the controls are there, they are just hidden, inside the Shadow DOM.

So now you’ve seen the Shadow DOM, let’s use it! To hide away all my crazy markup I’ve used to create the 12 Devs Logo I can make the #show-content div my Shadow DOM host, then populate it with the template’s content.

It will then act like the <audio> tag and not show the inner workings when inspected.

But wait up – where did all our styles go? Well the Shadow DOM comes with a Shadow Boundary. This means it automatically has scope, none of the global styles or scripts affect the local mark up and none of the local styles or scripts affect the rest of the page. (It’s worth noting you can reverse this with a little JavaScript if you so wish).

So let’s amend our template to include the styles we have externally in our style sheet. They still won’t affect anything because they are within the <template> tag, which as we know from earlier are inert.

Bring on Custom Elements

To create a Custom Element we need to register it via the document.register() method, which takes two arguments, the name of the new element (which needs to contain a hyphen), and a prototype, (optional), which must extend HTMLElement. So let’s create our prototype:

var twelveDevsNavProto = Object.create(HTMLElement.prototype);

This prototype comes with a createdCallBack method, which we can use to do all our Shadow DOM population shenanigans from earlier.

Both Mozilla and Google are building UI libraries based on web components. Mozilla have Brick and Google have Polymer, both are worth checking out.

And you’re done, pat yourself on the back, another thing explored and in your arsenal for the coming year!

Ruth John

Ruth is a web technologist and Google Developer Expert. She likes to educate people about new web technologies and inspire them to try them, coming up with exciting and engaging ways to use them. Her favourite things include interactive audio/visual installations and 80s cartoons, usually at the same time!