Web Components
Every element covered across this entire series so far — div, section, dialog, details — was built into the browser already. Web Components let you define a genuinely new HTML element, with its own behaviour and (optionally) completely isolated CSS. This chapter is an intentionally gentle introduction; Course 3 (Advanced) returns to this topic in full depth.
Custom Elements — Defining Your Own Tag
customElements.define('greeting', ...) (no hyphen) fails outright. The hyphen is specifically how the browser distinguishes a custom element from any current or future standard HTML tag, exactly the same reasoning behind the reserved data- prefix from Chapter 7.
connectedCallback — When the Element Actually Runs Its Setup
connectedCallback() runs when the element is actually inserted into the document — not when the class is defined, and not necessarily the instant the HTML parses it. This timing distinction matters once a custom element needs to read its own attributes or set up its initial content correctly.
Shadow DOM — Genuinely Isolated Internals
A custom element can attach a "shadow root" — a separate, encapsulated DOM subtree with its own scoped CSS that doesn't leak out to the rest of the page, and isn't affected by the rest of the page's CSS either.
Why This Matters — The Underlying Motivation
- True encapsulation — a genuinely reusable widget (a custom date picker, a rating-stars component) that can't have its internal styling accidentally broken by whatever CSS happens to exist elsewhere on a page it's dropped into.
- Framework-independent reuse — a properly built web component works in a React app, a Vue app, or a plain HTML page identically, since it's a genuine browser feature rather than tied to any specific JavaScript framework.
- Native, not a library dependency — unlike component systems baked into specific frameworks, this is built directly into the browser itself, requiring no external library to function at all.
<template> element from Chapter 8 (cloning a template's content into the shadow root is a common, cleaner pattern than building HTML via template literals as shown above), <slot> elements for letting users pass in their own content, and a fuller lifecycle than just connectedCallback. Course 3, Chapter 1 goes through all of this properly — this chapter exists purely to establish the core concept before that deeper dive.
Chapter 11 Quick Reference
- customElements.define('tag-name', ClassName) — registers a genuinely new HTML element
- Custom element tag names MUST contain a hyphen — a hard requirement, distinguishes them from standard/future HTML tags
- connectedCallback() — runs when the element is actually inserted into the document
- attachShadow({mode: 'open'}) — creates a shadow root, a genuine CSS encapsulation boundary
- Shadow DOM benefit: internal CSS never leaks out, page CSS never leaks in — eliminates accidental style collisions
- Framework-independent — a real browser feature, works identically across React/Vue/plain HTML
- Full depth (template/slot, full lifecycle) covered in Course 3, Chapter 1
- Next chapter (final, Course 2): practical project — building a real contact form / project page