Grow your CSS skills. Land your dream job.

A Guide to Web Components

Published by Guest Author

The following is a guest post by Rob Dodson (@rob_dodson). Rob and I were going back and forth in CodePen support getting Polymer (a web components polyfill, kinda) working on a demo of his. We did get it working, and things kind of evolved into this article. Take it away Rob.

Update: Rob updated this article on March 5, 2014, getting everything up to date, as this is a rather fast-moving technology at the moment.


Recently I was working with a client to train their internal teams on how to build web applications. During this process it occurred to me that the way we presently architect the front-end is very strange and even a bit broken. In many instances you’re either copying huge chunks of HTML out of some doc and then pasting that into your app (Bootstrap, Foundation, etc.), or you’re sprinkling the page with jQuery plugins that have to be configured using JavaScript. It puts us in the rather unfortunate position of having to choose between bloated HTML or mysterious HTML, and often we choose both.

In an ideal scenario, the HTML language would be expressive enough to create complex UI widgets and also extensible so that we, the developers, could fill in any gaps with our own tags. Today, this is finally possible through a new set of standards called Web Components.

Web Components?

Web Components are a collection of standards which are working their way through the W3C and landing in browsers as we speak. In a nutshell, they allow us to bundle markup and styles into custom HTML elements. What's truly amazing about these new elements is that they fully encapsulate all of their HTML and CSS. That means the styles that you write always render as you intended, and your HTML is safe from the prying eyes of external JavaScript.

If you want to play with native Web Components I'd recommend using Chrome Canary, since it has the best support. Be sure to enable the following settings in chrome://flags.

  • Experimental JavaScript
  • Experimental Web Platform Features
  • HTML Imports

A Practical Example

Think about how you currently implement an image slider, it might look something like this:

<div id="slider">
  <input checked="" type="radio" name="slider" id="slide1" selected="false">
  <input type="radio" name="slider" id="slide2" selected="false">
  <input type="radio" name="slider" id="slide3" selected="false">
  <input type="radio" name="slider" id="slide4" selected="false">
  <div id="slides">
    <div id="overflow">
      <div class="inner">
        <article>
          <img src="./rock.jpg" alt="an interesting rock">
        </article>
        <article>
          <img src="./grooves.jpg" alt="some neat grooves">
        </article>
        <article>
          <img src="./arch.jpg" alt="a rock arch">
        </article>
        <article>
          <img src="./sunset.jpg" alt="a dramatic sunset">
        </article>
      </div>
    </div>
  </div>
  <label for="slide1"></label>
  <label for="slide2"></label>
  <label for="slide3"></label>
  <label for="slide4"></label>
</div>

See the Pen CSS3 Slider by Rob Dodson (@robdodson) on CodePen

Image slider adapted from CSScience. Images courtesy of Eliya Selhub

That's a decent chunk of HTML, and we haven't even included the CSS yet! But imagine if we could remove all of that extra cruft and reduce it down to only the important bits. What would that look like?

<img-slider>
  <img src="./sunset.jpg" alt="a dramatic sunset">
  <img src="./arch.jpg" alt="a rock arch">
  <img src="./grooves.jpg" alt="some neat grooves">
  <img src="./rock.jpg" alt="an interesting rock">
</img-slider>

Not too shabby! We've ditched the boilerplate and the only code that's left is the stuff we care about. This is the kind of thing that Web Components will allow us to do. But before I delve into the specifics I'd like to tell you another story.

Hidden in the shadows

For years the browser makers have had a sneaky trick hidden up their sleeves. Take a look at this <video> tag and really think about all the visual goodies you get with just one line of HTML.

<video src="./foo.webm" controls></video>

There's a play button, a scrubber, timecodes and a volume slider. Lots of stuff that you didn't have to write any markup for, it just appeared when you asked for <video>.

But what you’re actually seeing is an illusion. The browser makers needed a way to guarantee that the tags they implemented would always render the same, regardless of any wacky HTML, CSS or JavaScript we might already have on the page. To do this, they created a secret passage way where they could hide their code and keep it out of our hot little hands. They called this secret place: the Shadow DOM.

If you happen to be running Google Chrome you can open your Developer Tools and enable the Show Shadow DOM flag. That'll let you inspect the <video> element in more detail.


The Show Shadow DOM option


Inspecting the Shadow DOM

Inside you'll find that there's a ton of HTML all hidden away. Poke around long enough and you'll discover the aforementioned play button, volume slider, and various other elements.

Now, think back to our image slider. What if we all had access to the shadow DOM and the ability to declare our own tags like <video>? Then we could actually implement and use our custom <img-slider> tag.

Let’s take a look at how to make this happen, using the first pillar of Web Components, the template.

Templates

Every good construction project has to start with a blueprint, and with Web Components that blueprint comes from the new <template> tag. The template tag allows you to store some markup on the page which you can later clone and reuse. If you've worked with libraries like mustache or handlebars before, then the <template> tag should feel familiar.

<template>
  <h1>Hello there!</h1>
  <p>This content is top secret :)</p>
</template>

Everything inside a template is considered inert by the browser. This means tags with external sources — <img>, <audio>, <video>, etc. — do not make http requests and <script> tags do not execute. It also means that nothing from within the template is rendered on the page until we activate it using JavaScript.

So the first step in creating our <img-slider> is to put all of its HTML and CSS into a <template>.

See the Pen CSS3 Slider Template by Rob Dodson (@robdodson) on CodePen

Once we've done this, we're ready to move it into the shadow DOM.

Shadow DOM

To really make sure that our HTML and CSS doesn't adversely affect the consumer we sometimes resort to iframes. They do the trick, but you wouldn't want to build your entire application in 'em.

Shadow DOM gives us the best features of iframes, style and markup encapsulation, without nearly as much bloat.

To create shadow DOM, select an element and call its createShadowRoot method. This will return a document fragment which you can then fill with content.

<div class="container"></div>

<script>
  var host = document.querySelector('.container');
  var root = host.createShadowRoot();
  root.innerHTML = '<p>How <em>you</em> doin?</p>'
</script>

Shadow Host

In shadow DOM parlance, the element that you call createShadowRoot on is known as the Shadow Host. It's the only piece visible to the user, and it's where you would ask the user to supply your element with content.

If you think about our <video> tag from before, the <video> element itself is the shadow host, and the contents are the <source> tags you nest inside of it.

<video>
  <source src="trailer.mp4" type="video/mp4">
  <source src="trailer.webm" type="video/webm">
  <source src="trailer.ogv" type="video/ogg">
</video>

Shadow Root

The document fragment returned by createShadowRoot is known as the Shadow Root. The shadow root, and its descendants, are hidden from the user, but they're what the browser will actually render when it sees our tag.

In the <video> example, the play button, scrubber, timecode, etc. are all descendants of the shadow root. They show up on the screen but their markup is not visible to the user.

Shadow Boundary

Any HTML and CSS inside of the shadow root is protected from the parent document by an invisible barrier called the Shadow Boundary. The shadow boundary prevents CSS in the parent document from bleeding into the shadow DOM, and it also prevents external JavaScript from traversing into the shadow root.

Translation: Let's say you have a style tag in the shadow DOM that specifies all h3's should have a color of red. Meanwhile, in the parent document, you have a style that specifies h3's should have a color of blue. In this instance, h3's appearing within the shadow DOM will be red, and h3's outside of the shadow DOM will be blue. The two styles will happily ignore each other thanks to our friend, the shadow boundary.

And if, at some point, the parent document goes looking for h3's with $('h3'), the shadow boundary will prevent any exploration into the shadow root and the selection will only return h3's that are external to the shadow DOM.

This level of privacy is something that we've dreamed about and worked around for years. To say that it will change the way we build web applications is a total understatement.

Shadowy Sliders

To get our img-slider into the shadow DOM we'll need to create a shadow host and populate it with the contents of our template.

<template>
  <!-- Full of slider awesomeness -->
</template>

<div class="img-slider"></div>

<script>
  // Add the template to the Shadow DOM
  var tmpl = document.querySelector('template');
  var host = document.querySelector('.img-slider');
  var root = host.createShadowRoot();
  root.appendChild(document.importNode(tmpl.content, true));
</script>

In this instance we've created a div and given it the class img-slider so it can act as our shadow host.

We select the template and do a deep copy of its internals with document.importNode. These internals are then appended to our newly created shadow root.

If you're using Chrome you can actually see this working in the following pen.

See the Pen CSS3 Slider Shadow DOM by Rob Dodson (@robdodson) on CodePen

Insertion Points

At this point our img-slider is inside the shadow DOM but the image paths are hard coded. Just like the <source> tags nested inside of <video>, we'd like the images to come from the user, so we'll have to invite them over from the shadow host.

To pull items into the shadow DOM we use the new <content> tag. The <content> tag uses CSS selectors to cherry-pick elements from the shadow host and project them into the shadow DOM. These projections are known as insertion points.

We'll make it easy on ourselves and assume that the slider always has four images, that way we can create four insertion points using nth-of-type.

<template>
  ...
  <div class="inner">
    <article>
      <content select="img:nth-of-type(1)"></content>
    </article>
    <article>
      <content select="img:nth-of-type(2)"></content>
    </article>
    <article>
      <content select="img:nth-of-type(3)"></content>
    </article>
    <article>
      <content select="img:nth-of-type(4)"></content>
    </article>
  </div>
</template>

Now we can populate our img-slider.

<div class="img-slider">
  <img src="./rock.jpg" alt="an interesting rock">
  <img src="./grooves.jpg" alt="some neat grooves">
  <img src="./arch.jpg" alt="a rock arch">
  <img src="./sunset.jpg" alt="a dramatic sunset">
</div>

This is really cool! We've cut the amount of markup that the user sees way down. But why stop here? We can take things a step further and turn this img-slider into its own tag.

Custom Elements

Creating your own HTML element might sound intimidating but it's actually quite easy. In Web Components speak, this new element is a Custom Element, and the only two requirements are that its name must contain a dash, and its prototype must extend HTMLElement.

Let's take a look at how that might work.

<template>
  <!-- Full of image slider awesomeness -->
</template>

<script>
  // Grab our template full of slider markup and styles
  var tmpl = document.querySelector('template');

  // Create a prototype for a new element that extends HTMLElement
  var ImgSliderProto = Object.create(HTMLElement.prototype);

  // Setup our Shadow DOM and clone the template
  ImgSliderProto.createdCallback = function() {
    var root = this.createShadowRoot();
    root.appendChild(document.importNode(tmpl.content, true));
  };

  // Register our new element
  var ImgSlider = document.registerElement('img-slider', {
    prototype: ImgSliderProto
  });
</script>

The Object.create method returns a new prototype which extends HTMLElement. When the parser finds our tag in the document it will check to see if it has a method named createdCallback. If it finds this method it will run it immediately. This is a good place to do setup work, so we create some Shadow DOM and clone our template into it.

We pass the tag name and prototype to a new method on the document, called registerElement, and after that we're ready to go.

Now that our element is registered there are a few different ways to use it. The first, and most straightforward, is to just use the <img-slider> tag somewhere in our HTML. But we can also call document.createElement("img-slider") or we can use the constructor that was returned by document.registerElement and stored in the ImgSlider variable. It's up to you which style you prefer.

Support

Support for the various standards that makeup Web Components is currently spotty, though improving all the time. This table illustrates where we're presently at.

But don't let the table discourage you from using them! The smarties at Mozilla and Google have been hard at work building polyfill libraries which sneak support for Web Components into all modern browsers! This means you can start playing with these technologies today and give feedback to the folks writing the specs. That feedback is important so we don't end up with stinky, hard to use syntax.

Let's look at how we could rewrite our img-slider using Google's Web Component library, Polymer.

Polymer to the Rescue!

Polymer adds a new tag to the browser, <polymer-element>, which automagically turns templates into shadow DOM and registers custom elements for us. All we need to do is to tell Polymer what name to use for the tag and to make sure we include our template markup.

See the Pen Polymer Slider by Rob Dodson (@robdodson) on CodePen

I find it's often easier to create elements using Polymer because of all the niceties built into the library. This includes two-way binding between elements and models, automatic node finding and support for other new standards like Web Animations and Pointer Events. Also, the developers on the polymer-dev mailing list are extremely active and helpful, which is great when you're first learning the ropes, and the StackOverflow community is growing.

This is just a tiny example of what Polymer can do, so be sure to visit its project page and also checkout Mozilla's alternative, X-Tag.

Issues

Any new standard can be controversial and in the case of Web Components it seems that they are especially polarizing. Before we wrap up, I want to open up for discussion some of the feedback I've heard over the past few months and give my take on it.

OMG it's XML!!!

I think the thing that probably scares most developers when they first see Custom Elements is the notion that it will turn the document into one big pile of XML, where everything on the page has some bespoke tag name and, in this fashion, we'll make the web pretty much unreadable. That's a valid argument so I decided to kick the bees' nest and bring it up on the Polymer mailing list.

The back and forth discussion is pretty interesting but I think the general consensus is that we're just going to have to experiment to see what works and what doesn't. Is it better, and more semantic, to see a tag name like <img-slider> or is our present "div soup" the only way it should be? Alex Rusell composed a very thoughtful post on this subject and I'd recommend everyone take the time to read it before making up their mind.

SEO

At this moment it's unclear how well crawlers support Custom Elements and Shadow DOM. The Polymer FAQ states:

Search engines have been dealing with heavy AJAX based applications for some time now. Moving away from JS and being more declarative is a good thing and will generally make things better.

Recent evidence suggests that search engines are able to understand custom elements to some degree. A good example is the Polymer website itself, which is built with custom elements and is easily searched in Google.

From speaking with members of the Polymer team I've learned that the general best practice is to make sure the content inside of your custom element is static, and not coming from a data binding.

<!-- probably good -->
<x-foo>
  Here is some interesting, and searchable content...
</x-foo>

<!-- probably bad -->
<x-foo>
  {{crazyDynamicContent}}
</x-foo>

<!-- definitely don't do this -->
<a href="{{aDynamicLink}}">Click here</a>

To be fair, this isn't a new problem. AJAX heavy sites have been dealing with this issue for a few years now and thankfully there are solutions out there.

Accessibility

Obviously when you're hiding markup in secret shadow DOM sandboxes the issue of accessibility becomes pretty important. Steve Faulkner took a look at accessibility in shadow DOM and seemed to be satisfied with what he found.

Results from initial testing indicate that inclusion of ARIA roles, states and properties in content wholly inside the Shadow DOM works fine. The accessibility information is exposed correctly via the accessibility API. Screen readers can access content in the Shadow DOM without issue.

The full post is available here.

Marcy Sutton has also written a post exploring this topic in which she explains:

Web Components, including Shadow DOM, are accessible because assistive technologies encounter pages as rendered, meaning the entire document is read as “one happy tree”.

Marcy also points out that the img-slider I built in this post is not accessible because our CSS label trick makes it inaccessible from the keyboard. Keep that in mind if you're looking to reuse it in a project.

Surely there will be bumps along the way but that sounds like a pretty great start!

Style tags? Um, no thanks.

Unfortunately <link> tags do not work inside of the Shadow DOM, which means the only way to pull in external CSS is through @import. In other words, <style> tags are — for the moment — unavoidable1.

Keep in mind that the styles we're talking about are relevant only to a component, whereas we've previously been trained to favor external files because they often affect our entire application. So is it such a bad thing to put a <style> tag inside of an element, if all of those styles are scoped just to that one entity? Personally I think it's OK, but the option of external files would be very nice to have.


1 Unless you use Polymer which gets around this limitation with XHR.

Now it's your turn

It's up to us to figure out where these standards should go and what best practices will guide them. Give Polymer a shot, and also look at Mozilla's alternative to Polymer, X-Tag (which has support all the way down to Internet Explorer 9).

Also, make sure you reach out to the developers at Google and Mozilla who are driving the bus on these standards. It'll take our feedback to properly mold these tools into something we all want to use.

While there are still some rough edges, I think Web Components will eventually usher in a new style of application development, something more akin to snapping together Lego bricks and less like our current approach, which is often plagued by excess boilerplate. I'm pretty excited by where all of this is heading, and I look forward to what the future might hold.

Comments

  1. Art Lawry
    Permalink to comment#

    Really interesting stuff here. Another step in the modular direction. This combined with element-queries could be quite powerful.

    A small bug: It looks as if the support table got the wrong figure associated with it. [Admin note]: fixed.

  2. Permalink to comment#

    Psssst! The browser support table is the wrong image.

  3. I’ve been interested in learning about the Shadow DOM for some time now, this is article is a good launching pad for me. I can’t wait to see where we can go from here.

    FYI, the browser support image is coming in as the Video Shadow DOM.

  4. Lukas
    Permalink to comment#

    So which one has more support right now, x-tags or polymer? Also, why don’t they just give us the polyfills + the functionality, and disclude all the extra elements. Isn’t the point of web components to kinda write your own and add your own semantics? Or am I misunderstanding this. Anyways, thanks for the article, this has answered a lot of my questions!

    • Permalink to comment#

      X-Tags uses some of the Polymer polyfills so the two projects are pretty related. X-Tags adds additional support to IE9 so if you need to work on that platform then X-Tags will be your best bet.

      You can work with just the polyfills if you want. Polymer separates them into two sections. platform.js is all the polyfills and polymer.js is all the framework-y bits (data binding, stuff like that). You can also run the individual polyfills if you only want one or two things.

    • Lukas
      Permalink to comment#

      @Rob Dodson Thank you, I didn’t know they were separated like that. I’ve got one more question though. Even if they ever do let you use the tag for css, because of the fact that the shadow dom doesn’t bleed out styles, wouldn’t you have to use multiple of them and thus have a slower page load time due to multiple requests? Or am i wrong/are they working on a fix for that.

  5. Peter Hentges
    Permalink to comment#

    The Polymer CodePen doesn’t render its result for me in Chrome 30 on Mac OS 10.6.8.

    This looks like an excellent tech coming down the pipe! I work for an online university and our course media re-uses components that would fit into this model very nicely, making production much more efficient.

  6. Robert Cannon
    Permalink to comment#

    You indicate that there is no support for this stuff in IE, but your non-Polymer CodePen works just great in IE 11. So, what is the IE support story?

    • Permalink to comment#

      Hm that’s odd…

      Microsoft has not implemented any of the specs to my knowledge. I’ve spoken to MS people about this and they’ve also publicly tweeted that they’re keeping an eye on Web Components but don’t have plans to implement them yet. I think you can follow their support of Shadow DOM here.

      It might be that IE11 is treating the template tag as HTMLUnknownElement and ignoring it. Then applying the rest of the styles to the tags inside of it. I don’t have a copy of IE11 to test on but if that’s the case then it’s accidental progressive enhancement :)

  7. Permalink to comment#

    Great writeup as usual!

    Re. SEO, we’re going to put up a video on polymer-project.org that has a bit more to grasp than the FAQ entry. The current answer is not filling.

    Re. in shadow dom: FWIW, last I heard, the spec gods were considering putting back addStyleSheet(). One thing Polymer does for you is convert your to and inline those rules in the element. This eases development and you don’t have to know the extra bits of shadow dom nuance. When we say “Polymer’s sugaring”, this is a great example. It’s something that makes building web components easier.

  8. Will Rowe
    Permalink to comment#

    Rob mentions that CSS can only be applied through a style tag in the template code, with no support for link tags currently. I know that it’s possible to alter the shadow DOM (like the video tag controls etc.) through CSS pseudo-elements selectors, as mentioned in this previous article. Would this be possible for web components as well?

  9. First off, nice article!

    You didn’t discuss security in the list of issues above. Specifically, I’m struggling to understand how Web Components fit with the iframe security model.

    JS security/isolation: If you have data associated with a third-party widget, you’ve still gotta load an iframe in order to execute JS or access storage without the underlying page having access, is that right?

    HTML security/isolation: If the rendered widget HTML contains sensitive info that you don’t want to expose to the underlying page, then, again, you’d need to wrap it in an iframe. Is that right?

    • Permalink to comment#

      Hey Jared,

      I don’t think Web Components add anything new in terms of JS or HTML security so all the current rules that you’ve cited still apply.

  10. Permalink to comment#

    Rob, thanks for sharing, this is really exciting! You have inspired me to get something to work for IE7 / IE8.

    I have put together a proof of concept, of a possible polyfill / alternate solution for older browsers.

    My code goes down a completely different route to the “standard”, but what I was hoping to achieve was some of the same end-goals, but in older versions of IE. I have only implemented some basics for now, but my code could be improved to add some of the other nice features you described. Maybe someone can extract the useful bits of my code and make a completely cross-browser compatible polyfill.

    Would you mind having a look here, and let me know what you think?
    http://www.smartmultimedia.com.au/web_components/

    This is the only HTML markup to add the web component to a page:

    <web-component data-type="tester">
       <h1>Component</h1>
       <p>This is my component</p>
    </web-component>
    
  11. This is really cool but I hope the <style> tag issues get sorted. Ideally I’d want to still style these components in my global, minified CSS file using some sort of special CSS selector.

    • dude, best gravatar ever

    • Permalink to comment#

      The <style> tag is primarily for the benefit of the component author. The author can expose a number of ways for the consumer to reach in and style the element from the outside. Those styles would live with the rest of your app’s CSS.

      I posted a couple of links higher up in the thread to a pair of articles I wrote on styling elements. I agree that it would be awesome to use external files for everything, and it sounds like the browser developers are working on that, but it’s really tricky because of all the new scenarios Shadow DOM and HTML Imports introduce.

    • Permalink to comment#

      Generally speaking, a web components is a sort of black box. Styling is a duty of the author, but customization is possible, Here you can see how I do that for my components library .

  12. Permalink to comment#

    Is Polymer supported by all the major browsers? I didn’t think it had widespread support at all yet.

  13. Alexander
    Permalink to comment#

    Really interesting article. I can foresee HTML “libraries” similar to the ones we know in jQuery.

    But since this will probably not get into IE anytime soon, I doubt I will have the chance to use it.

    • Permalink to comment#

      That’s where Polymer and X-Tags come in. They’re designed to sneak support into non-compliant browsers. I think of both libraries in the same way that I think of jQuery.

  14. Permalink to comment#

    I love this sort of stuff! It will be very interesting when this becomes more standardized, but in the meantime you can create this exact type of thing through AngularJS directives.

    • Permalink to comment#

      Yep that’s true. I know the Angular team is looking at Web Components and hopefully they’ll leverage them more in future versions. I can foresee a future where directives are replaced by components.

  15. Pierre
    Permalink to comment#

    I can see some advantages from a modular perspective. It will make sharing widgets much easier.

    However I’m a little concerned this will be the equivalent to cleaning your room by shoving the mess into the closet. “You caan’t see it so it must be clean right?” The great and bad thing about HTML is that it is completely free form. In addition its a very forgiving language many syntax errors don’t get caught.

    I’d be more confident in this solution if there were stronger syntax rules in place for code being produced. That way people could use web components knowing a certain level of quality was present. (Think Rails with it’s “convention over configuration” mantra)

    Either way the development of web components will be interesting to watch unfold.

    • Permalink to comment#

      That sounds an awful lot like XHTML. That HTML is so forgiving is a good thing! It enables many people, not just die hard coders, to easily publish and share information.

      But to your point about quality, I think we already deal with this now in the JS library world. We prefer libraries that are well written, actively developed and have a tidy codebase. Web Components won’t be any different.

    • Pierre
      Permalink to comment#

      I can see your point Rob about stricter rules on HTML. Like I mentioned in my post the forgivable nature of HTML is a blessing and a curse. It all depends on the author. And the portable nature of web components is appealing.

      I take your point about quality libraries naturally floating to the surface. But with today’s crowd sourcing mentality there’s still some pretty bad code snippets that get passed around. I think in general terms the community will govern itself, but I am still concerned that we’re masking potentially bad code by simply hiding it and making it less accessible.

  16. One problem I forsee with custom elements is that it will create some confusion with newer Web developers. If they look at the source code on someone’s Web page, how will they knew which elements are standard, and which are custom? We should encourage authors to use a “x-” prefix in front of their element names to show they are non-standard HTML elements, or maybe require this in the Web Components spec.

    Also, I noticed custom elements are created with JavaScript. What if the user has JavaScript disabled? They won’t be able to see anything of the custom element. And what will the user experience be like when first loading the page, before the JavaScript that creates the custom elements has been loaded? For example, in the img-slider element, before the element is loaded and running, will the user just see a row of four img elements on the page?

    • Permalink to comment#

      The spec requires that all custom elements have a dash, “-”, in their tag name. That’s how you can tell they’re non-standard. Initially, if I recall, they actually tried the “x-” thing but developers found it annoying having to write “x” over and over again when the dash would convey the same thing.

      Many of the HTML5 standards rely heavily on JavaScript so without it you’re going to be breaking a lot more than just Web Components. I honestly don’t know if the ability to turn it off in browsers is going to be around much longer. Firefox 23 removed the ability to do it in your settings (though you can still do it in about:flags I think). If your users are turning it off in large numbers then you probably don’t want to use Web Components.

      I didn’t mention HTML Imports in this post, but I’ve written about them on my blog and Eric Bidelman has a post on HTML5 Rocks that covers them. Typically you import elements at the top of the page using a <link rel="import"> tag. Imports load just like CSS so there is no FOUC.

  17. nmrony
    Permalink to comment#

    Simply Awesome Rob, Love it. Worthy reading

  18. Steven Sinatra
    Permalink to comment#

    I went to the meetup in Google Australia several weeks ago. Alex Danilo gave the link to the presentation he was explaining. Thought this would help here also.

    http://alex-webcomponents.appspot.com

    • Permalink to comment#

      Thanks Steven. That’s a really great deck, I used it a while back when I was first getting into the topic. One thing that I’ll point out is that the <element> tag has been removed so you can no longer declare custom elements that way. It was a big change and a lot of the articles and presentations out there still use it because the spec has changed so much in such a short amount of time.

      I put together a slide deck which clarifies some of the things that have changed. In particular the removal of the <element> tag, updated nomenclature for lifecycle callbacks and also the change from ::pseudo to ::part selectors. In fact, ::part has recently changed again to ^ and ^^ (“the hat and the cat”) selectors. I’ll have to write a blog post on that and leave it in this comment thread :)

  19. Flashwebz
    Permalink to comment#

    Lovely post, I like this sort of stuff, nice blog Rob I have read a full blog and very interesting and easily understand blog, very good job.

  20. First of all, you’ve got a very good HTML slider example here … :)

    I’m amazed at what HTML5 is able to do these days and the new web components you showed here is going to improve it even more. I think with these the Flash vs HTML war, finally has a winner ;)

    Thank you!

  21. Permalink to comment#

    Its a long time ago when I heard about @key-frame but I didnt thought that was as much easy as posted, I am feeling blessed, Thank you chris for the lovely post.

  22. Hi there this is kinda of off topic but I was wondering if blogs use WYSIWYG editors or if you have to manually code with HTML.
    I’m starting a blog soon but have no coding expertise so I wanted to get advice from someone with experience.

    Any help would be greatly appreciated!

  23. Jon Rimmer
    Permalink to comment#

    Safari supports Shadow DOM? Are you sure? That is contrary to everything other source I can find.

    In May, they were talking about removing the code from Webkit removing the code from Webkit because, following the Blink split, no port was using it.

    • Permalink to comment#

      Yeah that’s kind of a weird one. The webkitCreateShadowRoot method works in current versions of Safari and will allow you to hide stuff in a shadow root document fragment. But as you point out, there’s talk of the Safari team removing the underlying code that allows this. So it technically works today but might not tomorrow.

      I have seen some chatter from Apple folks on the Web Apps WG mailing list recently related to Custom Elements, so I’m hopeful they’re coming around.

  24. Tim Groleau
    Permalink to comment#

    Nice article, thanks! Web components and the shadow dom sound great, although for me, the question is nesting. We build components to simplify our lives, and we build complex components by composing simpler ones ad infinitum. I’m not seeing from this article how the shadow dom will work for that.

    • Permalink to comment#

      Hey Tim,

      The <content> tag allows you to nest web components inside of one another and have the whole thing render as you would expect. There’s also a <shadow> tag which we didn’t cover. I didn’t go super deep into the topic in order to keep the length of the post down, but Dominic Cooney and Eric Bidelman do a really good job explaining these topics in their HTML5 Rocks posts: Shadow DOM 101, Shadow DOM 301

    • Permalink to comment#

      The most interesting think of ShadowDom is css isolation. Web components css rules shoudn’t affect outer (and possibly inner) html. What about a rule like A { color: red !important;} into a not isolated web component? This was one of the main difficult I run into developing WebFragments.
      Nesting web components is also possible without shadow dom, it just depends on how it is implemented.

  25. Permalink to comment#

    So is it such a bad thing to put a STYLE tag inside of an element, if all of those styles are scoped just to that one entity?

    People need to accept that that’s perfectly acceptable. There’s absolutely nothing technically wrong with it and it doesn’t even go against best practices.

  26. Great article. I am curious about something though:

    In the section Insertion points you said:

    We’ll make it easy on ourselves and assume that the slider always has four images, that way we can create four insertion points using nth-of-type.

    How would you handle insertions, if you didn’t make this assumption?

    • Permalink to comment#

      I think if you were using native web components, you might need to build those pieces in JavaScript and pop them inside the template during the createdCallback. Or each slide could be its own custom element and then you could nest them inside of <img-slider> tag.

      If you’re using Polymer you might be able to come up with a solution using template repeat.

      So, I guess there are a few ways to go about it. I wanted to keep the example as simple as possible so it wouldn’t trip people up. That’s why I decided to hand code it like that.

    • That is what I thought… But if that is the case, I’m not sure I see yet how Web Components are superior to, lets say for example, jQuery plugins. Not saying that is not a cool thing, but I think Web Components still need a little more evolution.

      Maybe it is just a that Web Components is still a very young thing, or maybe I need to look more into it. Anyway, thank you for the article. Very interesting.

  27. Rohit
    Permalink to comment#

    Is that compulsory to use web components with Polymers and X-tags libraries only…?

  28. Chad Dattilio
    Permalink to comment#

    Hi there! I’m coming to you from the Future to say please please let’s not do this thing. I work at a company that some time in the past created these so-called “widgets” that encapsulate a bunch of markup / functionality, with the idea being you just pop them into the page and they just work! Problem is, they never work exactly how we want them to out of the box, and we’re stuck going through many, many different files that all depend on each other in mysterious ways. I am totally on board with the latest and greatest in our industry, but this black-boxing of functionality is not something we want. The maintainability of something like this is a nightmare. These are always over-engineered… because, well, the “user” developer will never see all the code in the background, right? Wrong. They’ll need to and they’ll end up cursing your name. Let’s nip this right in the bud.

  29. Hi Rob, have you ever add a Polymer element to codeopen.io ? I’d like to create a Pen of a polymer element we created. It’s a full javascript preloader( no gif animation). https://github.com/Urucas/priloader. Thanks

  30. Mark F. Simchock
    Permalink to comment#

    Quick question, please. And perhaps I read / pseudo-scanned a bit too quickly, but if one of the key ideas here is modularity and the ability to grow your own and then – ideally, I presume – share with others, aren’t there going to be naming conflicts.

    Much like prefixing with x- as someone mentioned above, should there be some sort of provision to mitigate namespace issues?

    Or is this minor and/or not an issue and I’m just too excited from the start of The World Cup to think straight?

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".