Web Components Β· Astro Tech Blog

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:

FeatureChromeFirefoxSafariEdge
Custom Elements v1βœ…βœ…βœ…βœ…
Shadow DOM v1βœ…βœ…βœ…βœ…
HTML Templatesβœ…βœ…βœ…βœ…
ES Modulesβœ…βœ…βœ…βœ…

Why Web Components?

BenefitDescription
Framework agnosticWorks anywhere HTML works
EncapsulatedStyles don’t leak in or out
ReusableWrite once, use everywhere
StandardNative browser API, no build tools needed
InteroperableCombine 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:

CallbackWhen 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