⚡IntermediateHTML APIs and Web Components

Web Components Overview

Combine Custom Elements, Shadow DOM, and HTML Templates to build reusable, framework-agnostic UI components.

Overview

Web Components is a suite of browser standards that together enable building fully encapsulated, reusable UI components using only HTML, CSS, and JavaScript no framework required. The four technologies: 1. Custom Elements: define new HTML tags with custom behavior 2. Shadow DOM: encapsulate styles and markup 3. HTML Templates: define reusable markup fragments 4. ES Modules: (standard JS) import/export components Web Components work in all modern browsers, can be used in any framework (React, Vue, Angular all consume them), and represent the platform's native component model.

Key Points

  • •Web Components combine Custom Elements + Shadow DOM + HTML Templates
  • •They work in all modern browsers natively no build step required
  • •Framework-agnostic: React, Vue, and Angular can all use web components
  • •Use LitElement or Lit (Google) for a lightweight ergonomic base class
  • •Web components expose a custom HTML API through attributes, properties, and events
  • •The component is a black box: public API is intentional; internals are encapsulated

Examples

A complete Web Component using all three technologies

<!-- HTML Template (defined once, reused) -->
<template id="toast-template">
  <style>
    :host {
      display: block;
      padding: 12px 20px;
      border-radius: 8px;
      font-family: sans-serif;
      background: var(--toast-bg, #1f2937);
      color: var(--toast-color, white);
    }
    :host([type="success"]) { background: #065f46; }
    :host([type="error"])   { background: #7f1d1d; }
    .message { font-size: 0.9rem; }
  </style>
  <span class="message">
    <slot></slot>  <!-- projected content -->
  </span>
</template>

<script>
class ToastMessage extends HTMLElement {
  static get observedAttributes() { return ['type']; }

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

  connectedCallback() {
    const tmpl  = document.getElementById('toast-template');
    const clone = tmpl.content.cloneNode(true);
    this.shadowRoot.appendChild(clone);
  }
}

customElements.define('toast-message', ToastMessage);
</script>

<!-- Usage in HTML -->
<toast-message type="success">Profile saved!</toast-message>
<toast-message type="error">Network error. Please retry.</toast-message>
<toast-message>New message received.</toast-message>

The component public API contract

<!-- Public API: attributes, properties, events, and slots -->

<!-- 1. Attributes (HTML API) -->
<my-rating value="4" max="5" readonly></my-rating>

<!-- 2. Properties (JavaScript API) -->
<script>
  const rating = document.querySelector('my-rating');
  rating.value = 3;               // set property
  console.log(rating.value);      // read property
</script>

<!-- 3. Custom Events (event API) -->
<my-rating onratingchange="handleChange(event)"></my-rating>
<!-- Inside component: this.dispatchEvent(new CustomEvent('ratingchange', { detail: { value: 3 } })) -->

<!-- 4. Slots (content API) -->
<user-card>
  <img slot="avatar" src="user.jpg" alt="User avatar">
  <span slot="name">Alice Smith</span>
</user-card>

Common Mistakes

  • Building complex web components from scratch use Lit or similar library for production
  • Not providing a clear public API (attributes, properties, events) internal details become hard to use
  • Forgetting that Shadow DOM breaks native form association need ElementInternals for custom form elements

Note

Web Components shine for design system tokens: a <ds-button>, <ds-badge>, or <ds-card> component works identically in React, Vue, plain HTML, and legacy jQuery apps. Build the component library once; deploy everywhere.

Exercises

Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

What are the three browser standards that form Web Components?