Web Components Cheat Sheet
Reference for building framework-agnostic UI with custom elements, Shadow DOM encapsulation, and HTML templates with named slots.
2 PagesIntermediateMar 10, 2026
Defining a Custom Element
A minimal component with a reactive attribute.
javascript
class UserCard extends HTMLElement { static get observedAttributes() { return ['name']; } constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { this.render(); } attributeChangedCallback(name, oldValue, newValue) { if (name === 'name') this.render(); } render() { this.shadowRoot.innerHTML = `<p>Hello, ${this.getAttribute('name')}!</p>`; }}customElements.define('user-card', UserCard);// Usage: <user-card name="Ada"></user-card>
Shadow DOM Encapsulation
Scoped styles that never leak in or out.
javascript
class StyledBadge extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); shadow.innerHTML = ` <style> /* Styles here are scoped to this component only */ span { background: gold; padding: 2px 8px; border-radius: 4px; } </style> <span><slot></slot></span> `; }}customElements.define('styled-badge', StyledBadge);// <styled-badge>New</styled-badge>
HTML Template & Slots
Named and default slots for content projection.
html
<template id="card-template"> <style>.card { border: 1px solid #ccc; padding: 1rem; }</style> <div class="card"> <slot name="title">Default Title</slot> <slot></slot> </div></template><!-- Consumer usage with named + default slots --><my-card> <h2 slot="title">Custom Title</h2> <p>This goes in the default slot.</p></my-card>
Core Web Components APIs
The three specs that make up the standard.
- customElements.define()- Registers a new custom element tag name mapped to a class
- Lifecycle callbacks- connectedCallback, disconnectedCallback, attributeChangedCallback, adoptedCallback
- Shadow DOM- attachShadow({mode}) creates an encapsulated, style-scoped DOM subtree
- <template>- Inert HTML fragment parsed but not rendered until cloned into the DOM
- <slot>- Placeholder inside shadow DOM where light-DOM children get projected
- Custom Events- dispatchEvent(new CustomEvent(name, {detail, bubbles: true})) for component communication
Pro Tip
Custom element names must contain a hyphen (e.g. user-card, not usercard) — this spec requirement reserves all-lowercase tag names for future native HTML elements and avoids naming collisions.
Was this cheat sheet helpful?
Explore Topics
#WebComponents#WebComponentsCheatSheet#WebDevelopment#Intermediate#DefiningACustomElement#ShadowDOMEncapsulation#HTMLTemplateSlots#CoreWebComponentsAPIs#OOP#CheatSheet#SkillVeris