Web Components let you build genuinely reusable, framework-agnostic custom HTML elements using only browser-native APIs — no React, Vue, or Svelte required.
class UserCard extends HTMLElement {
connectedCallback() {
const name = this.getAttribute('name');
const shadow = this.attachShadow({ mode: 'open' }); // encapsulated styles
shadow.innerHTML = <code>
<style>
.card { border: 1px solid #ccc; padding: 1rem; border-radius: 4px; }
</style>
<div class="card">
<strong>${name}</strong>
</div>
</code>;
}
}
customElements.define('user-card', UserCard);
<user-card name="Alice"></user-card>
The Shadow DOM is the key piece — styles defined inside it can’t leak out, and outside styles can’t leak in, giving true CSS encapsulation that a plain <div>-based component can never fully achieve, regardless of naming conventions.