Web Components

Web Components are a set of browser standards for building your own HTML tags. A component has a name, a private DOM and styles, and a public interface of attributes, properties and events. Because the browser understands them, they work in any page and with any framework.

Paradigm: Component-Oriented Programming

What Makes Web Components Special

  • Custom elements. customElements.define("user-badge", UserBadge) teaches the browser a new tag. The name must contain a hyphen.
  • Shadow DOM. attachShadow() gives the component a private tree. Its styles do not leak out, and page styles do not leak in, which is real encapsulation.
  • Lifecycle callbacks. connectedCallback, disconnectedCallback and attributeChangedCallback tell the component when it is added, removed or configured.
  • Attributes and events as the interface. Inputs arrive as attributes or properties, and outputs leave as DOM events, so components can be composed like ordinary HTML.
  • No build step. The standards are supported by all modern browsers. Libraries such as Lit make writing them shorter but are optional.

Example: A reusable user badge

class UserBadge extends HTMLElement {
  static observedAttributes = ['name'];

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() { this.render(); }
  attributeChangedCallback() { this.render(); }

  render() {
    const style = document.createElement('style');
    style.textContent =
      'span { padding: 2px 8px; border-radius: 8px; background: #0d6efd; color: white; }';
    const span = document.createElement('span');
    span.textContent = this.getAttribute('name') ?? 'anonymous';
    this.shadowRoot.replaceChildren(style, span);
  }
}

customElements.define('user-badge', UserBadge);

// In HTML:  <user-badge name="Ada"></user-badge>

How It Works

  • The class extends HTMLElement, so the browser treats it as a real element with the usual properties and events.
  • observedAttributes lists attributes to watch. When name changes, attributeChangedCallback re-renders the badge.
  • The style lives inside the shadow root. A global span rule elsewhere on the page cannot change the badge, and this rule cannot affect the page.
  • Setting textContent (instead of building HTML strings) means a hostile name cannot inject markup.

History and Where It Is Used

Web Components are used in design systems (Google's Material Web, Salesforce Lightning, GitHub's elements), embeddable widgets, and micro-frontends. Frameworks such as React, Vue, Svelte and Angular can consume and produce them. See the Demo 11 in this roadmap.

Learn More