Web Component Design
Building reusable web components using Web Components standards — Custom Elements, Shadow DOM, HTML Templates, lifecycle hooks, and framework-agnostic design.
When to Use
- Building framework-agnostic reusable UI components
- Creating design system components that work anywhere
- Encapsulating component styles with Shadow DOM
- Building micro-frontends with shared components
Component Lifecycle
class BaseComponent extends HTMLElement {
constructor() { super(); this.attachShadow({ mode: 'open' }); }
connectedCallback() { this.render(); this.addListeners(); }
disconnectedCallback() { this.removeListeners(); }
attributeChangedCallback(name, oldVal, newVal) { if (oldVal !== newVal) this.render(); }
static get observedAttributes() { return ['data-label', 'data-disabled']; }
render() {
this.shadowRoot.innerHTML = `
<style>:host { display: block; }</style>
<div part="container">${this.getAttribute('data-label')}</div>
`;
}
}
customElements.define('base-component', BaseComponent);
Common Pitfalls
- Over-styling — Shadow DOM hard to customize; use CSS custom properties and ::part
- Form participation — custom elements need ElementInternals for form integration
- Accessibility — ARIA roles and keyboard navigation aren't automatic
- Over-abstraction — not everything needs to be a web component
Verification Checklist
- Lifecycle properly implemented
- Shadow DOM for style encapsulation
- CSS custom properties for theming
- Attribute/property API documented
- Accessibility (ARIA, keyboard, focus)
- Tested in multiple frameworks