Web Components
debt(d7/e5/b3/t5)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints list Lighthouse and Chrome DevTools, but these don't automatically flag misuse patterns like missing observedAttributes, premature DOM manipulation, or framework coupling. No automated linting is indicated ('automated: no'). Misuse is silent until runtime — attributeChangedCallback silently never fires, Shadow DOM blocks external CSS without warning — requiring careful manual review or runtime debugging.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes a conceptual architectural shift: replacing framework-tied or jQuery-based widgets with native Custom Elements. This involves rewriting component logic, adjusting PHP templates to emit the new element tags, and potentially restructuring theming (CSS custom properties for Shadow DOM). Not a one-liner, but not a full cross-cutting architectural rework either.
Closest to 'localised tax' (b3). Web Components apply to the web context only, and once defined, a custom element is self-contained. The structural burden is localised — teams must follow the Custom Elements API conventions (constructor, connectedCallback, observedAttributes), but the rest of the codebase is largely unaffected. Shadow DOM encapsulation can impose a persistent theming tax but it stays within the component boundary.
Closest to 'notable trap — a documented gotcha most devs eventually learn' (t5). The misconception field states developers assume Web Components require a framework, which is a well-documented but common wrong belief. Additionally, common_mistakes include several non-obvious gotchas: missing super() silently breaks the constructor, omitting observedAttributes silently disables attributeChangedCallback, and Shadow DOM's CSS blocking surprises developers expecting normal style inheritance. These are documented but not intuitive.
Also Known As
TL;DR
Explanation
Web Components consist of three specs: Custom Elements (define new HTML tags with custom behaviour), Shadow DOM (encapsulated DOM subtree with scoped styles), and HTML Templates (<template> for inert markup). They work in all modern browsers without any build step or framework dependency. Shadow DOM provides true style encapsulation — styles inside do not leak out, styles outside do not leak in. Framework components (React, Vue) are built on similar concepts but require the framework to render.
Common Misconception
Why It Matters
Common Mistakes
- Not calling super() in the Custom Element constructor — required before accessing 'this'.
- Manipulating attributes before the element is connected to the DOM — use connectedCallback.
- Not defining observed attributes with static get observedAttributes() — attributeChangedCallback never fires without it.
- Forgetting that Shadow DOM style encapsulation blocks external CSS — use CSS custom properties for theming.
Code Examples
// Custom element without proper lifecycle:
class BadElement extends HTMLElement {
constructor() {
// Missing super() call
this.innerHTML = '<p>Content</p>'; // DOM manipulation before connected
}
}
class UserCard extends HTMLElement {
static get observedAttributes() { return ['name', 'role']; }
constructor() {
super(); // Required
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>:host { display: block; font-family: sans-serif; }</style>
<div class="card"><slot name="name"></slot></div>
`;
}
connectedCallback() { /* Element added to DOM */ }
attributeChangedCallback(name, old, val) { /* Attribute changed */ }
}
customElements.define('user-card', UserCard);