Web Components
Web Components are a set of browser APIs that let you create reusable, encapsulated custom HTML elements. They work across frameworks β use the same component in React, Vue, Angular, or vanilla HTML.
The Three Pillars
Web Components
βββ Custom Elements β Define your own HTML tags
βββ Shadow DOM β Encapsulated DOM and styles
βββ HTML Templates β Declarative markup fragments
What They Look Like
<!-- Your custom element, used like any HTML tag -->
<user-card name="Alice" role="Developer"></user-card>
<my-dialog>Hello World</my-dialog>
<star-rating value="4"></star-rating>
Browser Support
Web Components are supported in all modern browsers:
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Custom Elements v1 | β | β | β | β |
| Shadow DOM v1 | β | β | β | β |
| HTML Templates | β | β | β | β |
| ES Modules | β | β | β | β |
Why Web Components?
| Benefit | Description |
|---|---|
| Framework agnostic | Works anywhere HTML works |
| Encapsulated | Styles donβt leak in or out |
| Reusable | Write once, use everywhere |
| Standard | Native browser API, no build tools needed |
| Interoperable | Combine with any framework |
Simple Custom Element
class MyGreeting extends HTMLElement {
connectedCallback() {
this.textContent = 'Hello, Web Components!';
}
}
customElements.define('my-greeting', MyGreeting);
Demo: Hello Web Component
HTML
<my-greeting></my-greeting>
<my-greeting></my-greeting>
<pre id='wc-intro-out' style='background:#f1f5f9;padding:12px;border-radius:6px;'></pre> JavaScript
class MyGreeting extends HTMLElement {
connectedCallback() {
this.textContent = 'Hello from Web Component!';
this.style.cssText = 'display:block;padding:12px;background:#eef2ff;border-radius:6px;border:1px solid #c7d2fe;margin:4px 0;';
}
}
customElements.define('my-greeting', MyGreeting);
document.getElementById('wc-intro-out').textContent =
'Defined custom element: <my-greeting>\\n' +
'Each instance is independent.\\n' +
'Note: Define a custom element name must contain a hyphen (-).'; Live Output Window
The Component Lifecycle
Custom elements have lifecycle callbacks:
| Callback | When it fires |
|---|---|
constructor() | Element is created (before being added to DOM) |
connectedCallback() | Element is added to the DOM |
disconnectedCallback() | Element is removed from the DOM |
attributeChangedCallback(name, oldVal, newVal) | Observed attribute changes |
adoptedCallback() | Element is moved to a new document |
Observed Attributes
class UserCard extends HTMLElement {
static get observedAttributes() {
return ['name', 'role'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'name') {
this.querySelector('.name').textContent = newValue;
}
}
}
Without Shadow DOM (Light DOM)
By default, custom elements use the light DOM β their content is part of the main document. Styles from the page affect them, and their styles affect the page.
Whatβs Next
This section covers the foundation. Next topics dive deeper into:
- Custom Elements β full API with attributes, methods, events
- Shadow DOM β true style and DOM encapsulation
- Template Element β reusable markup with
<template> - Slots β composing content with named slots
- Shadow DOM Styling β CSS custom properties and parts
- Shadow DOM Events β event retargeting and composed events
Key Takeaways
- Web Components are a browser-native component model
- Three APIs: Custom Elements + Shadow DOM + Templates
- Custom element names must include a hyphen (
my-element) - Lifecycle callbacks:
connectedCallback,disconnectedCallback,attributeChangedCallback - Framework-agnostic β use anywhere HTML works
- No build tools or frameworks required β just vanilla JavaScript