HTML Web Components
In this page:
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?
<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
<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
<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
<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
<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
<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
<script src="webcomponents-loader.js"></script>
<my-widget></my-widget>
- Naming custom elements without a hyphen, which can cause conflict errors with future HTML standards.
- Attempting to style shadow DOM components from the global main page stylesheet directly.
- Writing visible code inside a template tag and expecting it to display on page load without cloning.
- 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.
Standard Web Component APIs are fully supported by all modern web browsers natively.
Chapter Quiz — Complete all 10 topics to unlock
0/10 topics done
Complete these topics first: