WebDev Bites: Web Components

custom tags with encapsulated style and behavior

Fig. 1 - HTML example using prism

        <div class="card">Hello WebDev World</div>
      
Fig. 2 - HTML example without prism Web components are encapsulated markup, styles, and JavaScript that implement some, often small, piece of functionality. It is instantiated with a tagged block like:
<code-viewer trim normalize-indent>
  [content goes here]
</code-viewer>
Tag names are required to be hyphenated by the W3C HTML specification to avoid conflicts with future standard tag additions. Prism is a JavaScript and css library designed to support syntax highlighting for many languages. The CodeViewer component was crafted to support optional use of prism. CodeViewer has many attributes that enable highly controlled rendering.

1.0 - Component Structure

The main parts of web components are: There several examples of components, including the code viewer above, that show a demo, discuss the design, and provide a description of the component interface. You can find a list of those by clicking the "Components" button in the left panel of this page.

2.0 - Component Parts Details

The table below, generated by ChatGPT 5, describes each of the component model parts in more detail.
Part Role in Component Component Code Examples
Custom element class Defines behavior by extending HTMLElement (or a built-in).
class XThing extends HTMLElement {
  constructor(){ super(); }
}
Lifecycle callbacks Hooks for setup/teardown and reacting to changes.
connectedCallback(){ /* init */ }
disconnectedCallback(){ /* cleanup */ }
static get observedAttributes(){ return ['value']; }
attributeChangedCallback(n,o,v){ /* react */ }
Registration (customElements.define) Makes the class available as a tag with a dash.
customElements.define('x-thing', XThing);
Shadow DOM Encapsulates DOM & styles; optional but common.
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `<div>...</div>`;
Template Reusable markup cloned into the shadow root.
const tpl = document.createElement('template');
tpl.innerHTML = `<style>:host{display:block}</style>`;
this.shadowRoot.append(tpl.content.cloneNode(true));
Scoped styling (:host, ::slotted) Style the host and projected children inside shadow.
this.shadowRoot.innerHTML = `
<style>
:host { display:inline-block; }
::slotted(span.badge){ font-weight:bold; }
</style><slot></slot>`;
Constructable Stylesheets Share CSS across instances via adoptedStyleSheets.
const sheet = new CSSStyleSheet();
sheet.replaceSync(':host{contain:content}');
this.shadowRoot.adoptedStyleSheets = [sheet];
Slots Project light-DOM content into the component.
this.shadowRoot.innerHTML = `
<slot name="label"></slot> <slot></slot>`;
Attributes ↔ properties Reflect external configuration into internal state.
get value(){ return this._v ?? ''; }
set value(v){ this._v = String(v); this.setAttribute('value', this._v); }
Events (CustomEvent) Emit outputs so parents can listen and react.
this.dispatchEvent(new CustomEvent('change', {
  detail: { value: this.value }, bubbles:true, composed:true
}));
Accessibility (ARIA & focus) Make it operable with keyboard/screen readers.
this.setAttribute('role','button');
this.tabIndex = 0;
this.addEventListener('keydown', e => {
  if(e.key==='Enter') this.click();
});
Form-associated (advanced) Participate in forms (value, validity, labels).
static formAssociated = true;
internals = this.attachInternals();
internals.setFormValue(this.value);
Styling hooks (::part, exportparts) Expose internals for external theming.
<button part="btn">Go</button>
/* outside component */
x-thing::part(btn){ border-radius:.5rem; }

3.0 - W3C Component References

The table below, generated by ChatGPT, lists intermediate level references for W3C components.
Reference What you’ll learn (plain-English focus) Notes / Level
Using Custom Elements (MDN) Defining a custom element class, lifecycle callbacks, and registering with customElements.define. Start here • Intermediate-friendly
Using Shadow DOM (MDN) Encapsulation, shadow roots, slot projection basics, and why styles don’t leak. Core concept • Clear diagrams
Using Templates & Slots (MDN) Structuring markup with <template> and composing with default/named <slot>. Hands-on examples
Web Components Guide (web.dev) Practical overview, patterns, and common pitfalls aimed at working developers. Broad survey • Best practices
Styling Components: :host, ::slotted, ::part (MDN) How to style the host element, projected children, and expose theming hooks. Styling toolbox
Constructable Stylesheets (MDN) Share CSS across instances with adoptedStyleSheets for performance and simplicity. Intermediate • Modern approach
Custom Events (MDN) Emit CustomEvent with detail, choose bubbles/composed, and design outputs. Event API essentials
Form-Associated Elements (MDN) Make components participate in forms: value, validation, labels, and attachInternals(). Intermediate+ • Very useful for inputs
Accessibility in Custom Elements (web.dev) ARIA roles, keyboard handling, focus management, and screen-reader considerations. Must-read • Practical tips
CustomElementRegistry (MDN) Understanding the registry, defining/upgrading elements, and avoiding name clashes. Reference • Concise