Web components tutorial

What are web components?

This quick, interactive tutorial introduces the basics of what web components are, how they work, and why they're useful. Each short section introduces a single concept, then lets you try out that concept in a live demo.

Time required: 5–10 minutes

The basic idea

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, <elix-auto-size-textarea> is a custom HTML tag defined by a new web component. Like most HTML tags, a web component starts with an opening <elix-auto-size-textarea> tag and ends with a closing </elix-auto-size-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:

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

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 loading JavaScript modules. The JavaScript source code for this site includes import statements like this:

import AutoSizeTextarea from 'elix/src/AutoSizeTextarea.js';

Such declarations allow the application to load definitions for custom elements like <elix-auto-size-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. Exactly how that is done can vary. In the case of the Elix components, you have a few basic options:

  1. Have your JavaScript import the module for the component you want using an import statement like the one above. Then compile and bundle your application using whatever development tools you are already using (Babel, webpack, etc.).
  2. Use the JavaScript module directly on an HTML page via a script tag that includes type="module". E.g.:
    <script type="module" src="https://component.kitchen/modules/AutoSizeTextarea.js"></script>
    You'll have a chance to try using such a script tag later in this tutorial. This approach only works on newer browsers (as of this writing, Chrome, Safari, and Edge).
  3. Compile and bundle the component module into an regular JavaScript ES5 script file loaded via a traditional script tag.

Regardless of how the component is packaged and loaded, you’ll generally need to host its module or script somewhere on 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 <elix‑sliding‑carousel> component to navigate between the images.

Then change the outer, parent element from a <elix‑sliding‑carousel> to a <elix‑tabs> element. Don’t forget to change both the opening and closing tags. Both types of components can display the images, but <elix‑tabs> displays the images in a set of tabbed pages.

<elix-carousel> <img aria-label="Lake" src="tutorial/image1.jpg"> <img aria-label="Horses" src="tutorial/image2.jpg"> <img aria-label="Mountain" src="tutorial/image3.jpg"> <img aria-label="Trees" src="tutorial/image4.jpg"> <img aria-label="Ocean" src="tutorial/image5.jpg"> </elix-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 <elix‑sliding‑carousel> component that presents its child elements in carousel style. Changing the demo to use a <elix‑tabs> switches to a component that displays tabbed pages of 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 elix-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.)

<elix-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> </elix-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 <elix-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 an <elix‑carousel>. You’ll end up with one type of component inside of another. Those two components could come from completely different companies or projects. As long as a user interface element is built using the web component standards, you can combine it however you like without trouble.

<style> cat-picture { height: 180px; width: 240px; } </style> <div> <cat-picture></cat-picture> <cat-picture></cat-picture> <cat-picture></cat-picture> <cat-picture></cat-picture> </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 things to work.

In contrast, web components are based on HTML standards, so components cooperate and work well together. If someone creates a cat‑picture component you want to use in your app (or a charting component, or a data grid component, etc.), you can add that to your application with confidence that things will work as you expect.

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.

<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!

Lesson 8: Try a component in your own project

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

Your mission: Use the elix-auto-size-textarea component in your own web project.

  1. Copy the following to the clipboard:

    <script type="module" src="https://component.kitchen/modules/AutoSizeTextarea.js"></script>
    <elix-auto-size-textarea minimum-rows="2" placeholder="Type all you want here!">

    This includes all the pieces you need to use an instance of the elix-auto-size-textarea component on any site: the <script> that loads the webcomponents-lite.js compatibility library, the <script> tag that imports the component itself as a module (note the use of type="module"), 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.