← Back to HTML Course | Chapter 8: Modern HTML & Components | Lesson 4 of 10

HTML Web Components

Imagine building a large Lego castle. If you had to piece together every single brick individually every time you wanted to add a window, it would take hours. Instead, you use pre-assembled window pieces that you can snap into place with a single click. HTML Web Components do exactly that. They allow you to build custom, reusable HTML elements (like your own custom tags) that contain their own structure, designs, and behavior. You can package a complex, interactive widget into a single custom tag, and use that tag across your website as easily as a standard paragraph or link.

What are Web Components?

Web Components are a set of modern web APIs that allow developers to create custom, reusable, and encapsulated HTML elements that function natively across all web applications.

Note: Custom element names must always contain a hyphen (like ) to prevent conflicts with future HTML elements.

Warning: Web Components require JavaScript to define their structure and behavior, so they will not function if scripts are disabled.

Example: What are Web Components?

markup
<my-widget></my-widget>

The Shadow DOM

The Shadow DOM allows your custom component to have its own isolated DOM tree that is completely separate from the main page. This ensures that the styles inside your component do not leak out, and the styles on the main page do not accidentally break your component.

Note: Use Shadow DOM to keep your component's styling completely isolated and safe from global page style rules.

Warning: Elements inside a closed Shadow DOM cannot be accessed or styled by standard global page scripts.

Example: The Shadow DOM

markup
<script>
  class MyWidget extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({ mode: 'open' });
    }
  }
</script>

The Custom Elements API

The Custom Elements API is used to register your custom HTML tags with the browser. You write a JavaScript class that extends the standard HTMLElement class, defining what HTML and styles should render when your custom tag is called.

Note: Define your custom element classes in separate, clean script files to keep your codebase modular.

Warning: Ensure you register your custom element using window.customElements.define before attempting to call the tag in your HTML.

Example: The Custom Elements API

markup
<script>
  class MyWidget extends HTMLElement {}
  window.customElements.define('my-widget', MyWidget);
</script>
<my-widget></my-widget>

Component Attributes

You can pass custom data values to your Web Components using standard HTML attributes. By observing and listening for changes to these attributes inside your component class, you can update your component dynamically.

Note: Use the observedAttributes and attributeChangedCallback methods to make your components responsive to attribute changes.

Warning: All attribute values are passed to your component as plain strings, so you must convert them to other formats manually if needed.

Example: Component Attributes

markup
<my-widget color="blue"></my-widget>
<script>
  class MyWidget extends HTMLElement {
    static get observedAttributes() { return ['color']; }
    attributeChangedCallback(name, oldVal, newVal) {
      console.log(name, newVal);
    }
  }
</script>

Component Templates

Writing your component's HTML markup directly inside JavaScript strings can be cluttered and hard to maintain. Using the template element allows you to define your component's markup cleanly in your HTML file, and clone it when your component class runs.

Note: Use templates to separate your component's HTML structure from your JavaScript code.

Warning: Template content is inert and hidden when the page loads, so you must clone its node structure inside your script to instantiate it.

Example: Component Templates

markup
<template id="widget-template">
  <p>Reusable markup</p>
</template>
<script>
  const clone = document.getElementById('widget-template').content.cloneNode(true);
</script>

Custom Element Lifecycle Callbacks

Custom elements support special lifecycle methods that run automatically at key moments: connectedCallback runs when the element is added to the page, disconnectedCallback runs when it is removed, and attributeChangedCallback runs whenever one of its watched attributes changes value.

Note: Use connectedCallback to set up event listeners and disconnectedCallback to clean them up, preventing memory leaks when the element is removed.

Warning: Forgetting to remove event listeners inside disconnectedCallback can cause memory leaks in long-running single page applications.

Example: Custom Element Lifecycle Callbacks

markup
<script>
  class MyWidget extends HTMLElement {
    connectedCallback() { console.log('added to page'); }
    disconnectedCallback() { console.log('removed from page'); }
  }
</script>

Browser Support and Polyfills

Custom elements and Shadow DOM are supported in all modern browsers including Chrome, Firefox, Safari, and Edge, but very old browsers like Internet Explorer 11 do not support them at all. For projects that must support such old browsers, polyfill libraries can add approximate support, though with some limitations.

Note: Check your actual visitor analytics before investing time in polyfills — most modern audiences no longer need them at all.

Warning: Polyfills for web components can add noticeable extra script weight to your page and never perfectly replicate native browser behavior in every edge case.

Example: Browser Support and Polyfills

markup
<script src="webcomponents-loader.js"></script>
<my-widget></my-widget>
Common Mistakes
  1. Naming custom elements without a hyphen, which can cause conflict errors with future HTML standards.
  2. Attempting to style shadow DOM components from the global main page stylesheet directly.
  3. Writing visible code inside a template tag and expecting it to display on page load without cloning.
Chapter Summary
  • Web Components let developers create custom, reusable HTML elements that function natively.
  • The Shadow DOM provides style encapsulation, preventing local component styles from leaking out.
  • Define component structures using HTML templates and register custom elements with the browser using the Custom Elements API.
Browser Support

Standard Web Component APIs are fully supported by all modern web browsers natively.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.