Web components tutorial

Supercharge your HTML powers with this quick interactive introduction to web components, a new HTML technology that makes it much easier to create great web sites and apps. This tutorial will teach you the basics of using web components. Each short lesson in this tutorial introduces a single concept, then gives you a chance to try out your new, supercharged web skills in a live demo.

Every web app or site you’ve ever made was created with the standard set of 100 or so HTML elements: <div>, <img>, and so on. The standard set changes very slowly, because it can take years to get enough people to agree on, say, a new <dialog> element.

A new set of HTML standards now defines something called a web component, letting anyone create and use their own HTML elements. These custom elements look and work just like the standard ones, but can be used without requiring that the whole industry agree upon them.

If you’ve ever edited HTML, you already know nearly everything that you need to know to use web components. Creating complex new web components in JavaScript is beyond the scope of this introduction, but we’ll give you a taste for what it’s like to create a simple component using only HTML. You don’t need to know any JavaScript to complete this tutorial and start using web components.

Lesson 1: Add a web component just by adding its HTML tag

Your mission: Add a single web component to the little demo below. Simply type, copy-and-paste, or drag-and-drop the following line to the end of the HTML:


You should end up with a new box at the bottom of the demo: a web component that automatically grows as a user types into it. Type in it and compare its behavior with that of the standard textarea.

<h4>Here's a simple demo</h4> <textarea>This standard textarea doesn’t grow when you type into it.</textarea>

Details: This demo starts out with a heading and a standard <textarea> for letting a user enter multiple lines of text. That standard <textarea>, unfortunately, doesn’t automatically get bigger as a user enters text. Users today expect a higher degree of polish than that, and they might be disappointed with the behavior of this plain <textarea>. Making a textarea automatically grow turns out to be tricky, and the solution requires some complex CSS and JavaScript. The good news is that someone else has already packaged up a good solution to that problem as a web component.

Here, <basic-autosize-textarea> is a custom HTML tag defined by a new web component. Like most HTML tags, a web component starts with an opening <basic-autosize-textarea> tag and ends with a closing </basic-autosize-textarea> tag. These work just like other HTML tags; they produce an instance of the indicated component at the spot where you place the tags.

A web component’s name needs to be longer than standard HTML tags because the universe of custom web components is much larger. Also, note that the component name includes hyphens (“-”). HTML requires that custom elements include at least one hyphen in their name, so a browser can tell standard HTML elements and web components apart. What works for the browser will work for you, too — from now on, if you ever see a hyphen in an HTML tag, you’ll know that you’re looking at a web component.

This particular demo, and most of the others on this page, is already set up for you to use the required components. A little later on, you’ll see how to start from scratch and allow any web page to use a given web component.

Lesson 2: Use web components in any modern browser

Your mission: Confirm for yourself that web components work in all modern browsers! These browsers include:

If you have one of these browsers installed, try opening this page in that browser and confirm this demo works in it.

<p> This auto-sizing text input component should work in all modern browsers: </p> <basic-autosize-textarea></basic-autosize-textarea>

Details: Web components are based on a new set of web standards that are still being officially adopted. In the past, a change in standards would have meant waiting an eternity for all popular browsers to support the feature — and for most users to upgrade to a version that included the change. But it turns out that you can use web components in your app or site today.

A compatibility library (known as "polyfills") called webcomponents.js lets web components work on any modern desktop or mobile browser. (Here, “modern” means any browser that’s capable of updating itself.) The demos on this page already include the webcomponents.js library, so they should work in all the supported browsers. To use web components in your own app or site, you can include the webcomponents.js compatibility library on your page.

Lesson 3: Load the components you want to use

On this page, all the components you need have already been loaded for you. That was accomplished through regular <script> tags like this:

<script href="basic-autosize-textarea.js"></script>

The browser uses such scripts to load definitions for custom elements like <basic-autosize-textarea>. Without that step, the browser wouldn’t know what the custom tags meant, and the page wouldn’t look correct.

Details: Before you can use a component on your web page, you need to tell the browser about it. The way to do this varies based on how the component was written and packaged up:

Regardless of how the component is packaged and loaded, you’ll need to make its script or HTML file available somewhere visible to your web site.

Lesson 4: Populate a component with “child” elements

Your mission: Replace one component with another and see how they treat their contents differently. First, try using the <simple-carousel> component to navigate between the images.

Then change the outer, parent element from a <simple-carousel> to a <simple-slideshow> element. Don’t forget to change both the opening and closing tags. Then wait a couple of seconds for the slideshow to start. Both types of components can display the images, but <simple-slideshow> automatically cycles through the images instead of waiting for the user to do so.

<simple-carousel> <img src="tutorial/image1.jpg"> <img src="tutorial/image2.jpg"> <img src="tutorial/image3.jpg"> <img src="tutorial/image4.jpg"> <img src="tutorial/image5.jpg"> </simple-carousel>

Details: As you already know, most of the standard HTML tags such as <p> and <div> allow you to put other elements inside them. Putting elements inside other elements is what lets you build up a complex and interesting web page. Technically speaking, the inner elements are called “child” elements, and the outer element is the “parent”.

What the parent element does with its children can vary, as does the kind of child elements a parent will understand. For example, you generally only use <li> (list item) elements inside a <ol> (ordered list) or <ul> (unordered list). With other elements, such as <img>, you generally don’t use child elements.

Like the standard HTML elements, web components can do interesting things with the child elements you put inside them. Exactly what a web component does with its child elements will depend on the component. This demo starts with a <simple-carousel> component that presents its child elements in carousel style. Changing the demo to use a <simple-slideshow> switches to a component that automatically cycles through its child elements.

Lesson 5: Use attributes to customize a component

Your mission: Update the list box so that it shows a particular item selected by default. When the basic-list-box component loads, no item is selected by default. Change that by editing the value attribute with the text of an item you would like to have selected by default, such as value="Orange". You can also set the selected item by position instead of its text: remove the value attribute, and add an attribute selected-index="5". (The index of the first item is 0.)

<basic-list-box value="" style="height: 200px;"> <div>Apple</div> <div>Apricot</div> <div>Banana</div> <div>Blackberry</div> <div>Blueberry</div> <div>Cherry</div> <div>Date</div> <div>Grape</div> <div>Lemon</div> <div>Lime</div> <div>Orange</div> <div>Peach</div> <div>Pear</div> <div>Pineapple</div> <div>Plum</div> <div>Raspberry</div> <div>Strawberry</div> <div>Watermelon</div> </basic-list-box>

Details: If you’ve written HTML, you’ve already used attributes to configure the behavior of standard HTML elements with attributes. You’ve done this by adding text such asid="message" inside an element’s opening tag. For example, you may have set the destination of a web link by setting an href attribute, as in <a href="hello.html">.

In the same way, you can use attributes to configure the behavior of a web component. In this demo, a <basic-list-box> component lets you select an item by default by setting the component’s value or selected-index attributes.

Most components you find will support their own particular set of attributes. Exactly which attributes a component supports depends on the component; you’ll need to read the component’s documentation, or look at examples of its use, to figure out which attributes it supports.

Lesson 6: Reliably mix standards-compliant components from different sources

Your mission: Change the plain <div> into a <simple-slideshow> or <simple-carousel>. You’ll end up with one kind of component, made by Google, inside a different kind of component made by an open source project. Those two entities have no formal connection, and didn’t coordinate the creation of these components. Nevertheless, because both organizations created components based on the new web component standards, you can use these components together without trouble.

<div> <google-chart type="column" style="height: 150px; width: 200px;" data="tutorial/data1.json"> </google-chart> <google-chart type="pie" style="height: 150px; width: 200px;" data="tutorial/data1.json"> </google-chart> <google-chart type="bar" style="height: 150px; width: 200px;" data="tutorial/data1.json"> </google-chart> </div>

Details: There are plenty of web user interface widgets out there, but they can’t work together unless they follow a standard that defines interoperability. So you usually can’t stick an existing widget from one place inside a widget from someplace else and expect to get the result you desire. In contrast, web components are based on forthcoming HTML standards, so components cooperate and work well together.

Lesson 7: Avoid style conflicts by using web components

Your mission: Observe how the CSS inside a component changes only elements inside that component, not elements outside it on the page. This demo has a sample component that wants <strong> text to be green and uppercase, but that CSS rule doesn’t affect the <strong> text outside the component. Moreover, styles on the outer page don’t affect elements inside the component. Edit the demo’s CSS rule for strong text to include an attribute like color: red;. No matter what you put in that rule — even an !important directive — it won’t affect the <strong> text inside the sample component.

This aspect of web components uses a new HTML feature called Shadow DOM which your browser already supports. This creates an invisible “shadow” boundary around the <component-with-styles>, preventing CSS rules inside that component from affecting the page, and vice versa. This lesson has adapted itself to take advantage of that feature so you can see how the shadow boundary keeps page and component styles from interfering with each other. If you’d like to see for yourself how component styles work in older browsers such as (at the time of this writing) Apple Safari or Microsoft Internet Explorer, run through this same demo in one of those browsers.

Your mission: Observe how the CSS inside a component changes only elements inside that component, not elements outside it the page. This demo has a sample component that wants <strong> text to be green and uppercase, but that CSS rule doesn’t affect the <strong> text outside the component.

This aspect of web components uses a new HTML feature called Shadow DOM which your browser does not yet support. Instead, the webcomponents.js library discussed earlier lets web components work even in browsers like yours. This support comes with some limitations, however: styles you add to the page will affect elements inside components.

Edit the demo’s CSS rule for strong text to include an attribute like color: red;. The rule will affect <strong> elements inside the sample component. The side effects here may be minor, but in other cases, they could prevent a component from working correctly.

To avoid such problems, change the CSS rule to affect strong.warning, that is, <strong> elements with the “warning” class. Then, add that class to the <strong> element on the page so that it looks like <strong class="warning">. That ensures your CSS rule only targets your strong text elements, not strong text inside web components.

<style> strong { } </style> This demo page includes <strong>strong</strong> text. <component-with-styles></component-with-styles>

Details: Until now, one of the biggest problems with mixing widgets or HTML from other places into your web page has been CSS style conflicts. Maybe you’ve been using a CSS class called .main. One day, you drop in a menu bar widget that also wants to use .main in its own CSS, and a visual disaster ensues.

To avoid these problems, a web component has an invisible boundary around it that keeps your page and the component looking the way they should. That invisible boundary is called the “shadow” boundary. By default, CSS you define on your page won’t mess up the component, and any rules defined in the component won’t mess up your page.

The demo shows a simple page with text on it, some of which is emphasized with a <strong> tag. The page also contains a sample component called <component-with-styles>. That component's complete definition is not shown here, but it includes some text and the following CSS:

strong {
  color: green;
  text-transform: uppercase;

This CSS rule says that any <strong> text inside the component should be green and uppercase. Notice that the component’s styles only change what things look like inside the component; they do not change the appearance of any strong elements in the outer demo. This shows that, when you add a web component to your project, you generally don’t have to worry about it messing up everything else on the page!

As noted above, component styling works differently in older browsers that don’t yet support HTML’s new Shadow DOM feature. In those browsers, Google's webcomponents.js library works behind the scenes to try to prevent styles inside components from affecting your HTML in the outer page. As a result, even on an older browser, the green styling in the sample component above still won’t affect the <strong> text in the demo’s first sentence.

However, older browsers may sometimes show styling issues in the other direction: the CSS you write for your page may inadvertently affect elements inside a web component. If you run through this demo on an older browser, you’ll see that setting the CSS for strong elements outside the component will affect the <strong> text inside the component.

To avoid that, you would need to change your CSS rule to target a class, such as strong.warning, and then in your HTML use <strong class="warning">. That helps ensure your CSS targets only the strong text outside the component, and not strong text inside any web components. This is not a perfect solution — as noted earlier, different groups may try to use the same CSS class names, resulting in style conflicts — but this is the best that can be done until all browser vendors have implemented support for the new HTML Shadow DOM feature.

To see how the new Shadow DOM feature in HTML helps make web components even better, open this page in a newer browser such as Google Chrome, and run through this same demo. You’ll see how styles on the page can’t accidentally change what happens inside a component. While a large number of users already have a browser that supports Shadow DOM, until all of your users have such a browser, you’ll want to keep these older browsers in mind when writing CSS in a project that uses web components.

Lesson 8: Try a component in your own project

Now that you’ve learned the basics of web components, it’s time to use a web component in one of your own projects! We’ve put together a service on Component Kitchen that makes it easy for you to try a web component in your own site or app.

This may be particularly useful to you if you are an HTML-level author who doesn’t want to have to learn developer tools. If you are a web developer, you’ll still find this service to be a fast way to try out a component. (Developers who want complete control over source code that incorporates components should check out the approaches described on Google’s Polymer site or the open webcomponents.org site.)

Your mission: Use a web component in your own web project.

  1. Copy the following to the clipboard:

    <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.20/webcomponents.min.js"></script>
    <script src="http://basicwebcomponents.org/basic-web-components/packages/basic-autosize-textarea/dist/basic-autosize-textarea.js"></script>
    <basic-autosize-textarea minimum-rows="2" placeholder="Type all you want here!">

    This includes all the pieces you need to use an instance of the basic-autosize-textarea component on any site: the <script> tag that loads the webcomponents.js compatibility library, the <script> tag that imports the component itself, and a sample use of the component.

  2. Open a web page in your preferred HTML editor. Or, if you don’t have a project underway, open JSBin, a free web-based HTML page editor.
  3. In the HTML editor, paste the text you copied above into the page’s <body>.
  4. Run your project, and see the live component running in your app!

That’s all there is to it

This concludes your introduction to web components! We hope you’ve seen that web components are a cool technology that’s ready for use today in your production web site or app.

If you found this tutorial useful, please let others know.


Sample images by Jacek Halicki (Wikimedia Commons, CC BY-SA 3.0), Myrabella (Wikimedia Commons, CC-BY-SA-4.0), ©CEphoto (Uwe Aranas, CC-BY-SA-3.0), ©Dietmar Rabich (rabich.de, CC BY-SA 4.0).