Skip to content

Day 2 Web Component Overview

The following quick summary is AI-Generated using Bing Copilot.

Here’s a concise review summary for each Learning Outcome Guide you listed. I’ve kept them short but clear so they can serve as quick reference points:


Web Components are a set of standardized APIs (Custom Elements, Shadow DOM, HTML Templates) that enable creating reusable, encapsulated UI elements. Benefits include modularity, style encapsulation, and framework independence.


Define a class extending HTMLElement, register it with customElements.define(), and attach DOM content via innerHTML or templates. Example: <my-element></my-element>.


The Shadow DOM isolates a component’s internal structure and styles from the global DOM, preventing CSS leaks and ensuring predictable rendering.


Templates (<template>) provide reusable markup, while slots (<slot>) allow content projection into components for flexibility and dynamic composition.


Styles placed inside the shadow root apply only to that component, ensuring true encapsulation without affecting global styles.


  • Global styles: Apply everywhere.
  • Shadow styles: Scoped to the component.
  • Encapsulation: Prevents style conflicts and promotes modular design.

Use --variables in styles to allow external customization of component appearance without breaking encapsulation.


Modify styles programmatically using this.shadowRoot.querySelector() or by updating CSS variables dynamically.


Attributes are string-based and reflected in HTML; properties are JavaScript-based and allow richer data types. Use observedAttributes for attribute changes.


Dispatch events using this.dispatchEvent(new CustomEvent('event-name', { detail })) so parent elements can listen and react.


Define public methods and properties on the component class for external scripts to call, enabling controlled interaction.


Maintain internal state in class fields and synchronize with attributes using setters/getters or attributeChangedCallback.


Store component-specific data in private fields or reactive patterns to manage UI updates internally.


Use getters/setters for dynamic property access and validation, ensuring controlled updates and reactivity.


Update DOM when state changes by re-rendering or manipulating shadow DOM nodes for a responsive UI.


  • connectedCallback: Initialization when added to DOM.
  • disconnectedCallback: Cleanup when removed.
  • attributeChangedCallback: Respond to attribute updates.

Testing ensures reliability, maintainability, and prevents regressions. Web Components need tests for rendering, behavior, and integration.


Use frameworks like Jest or Mocha with DOM simulation tools (e.g., JSDOM) to test components outside the browser.


Verify component rendering, attribute/property handling, event emission, and state updates using assertions.


Mock dependencies or external APIs to isolate component logic and ensure tests focus on internal behavior.


Run tests via CLI, review pass/fail results, and debug failing cases to improve component quality.


  • APIs: Custom Elements, Shadow DOM, HTML Templates.
  • Benefits: Reusable, encapsulated, framework-agnostic.

  • Define:
    class MyElement extends HTMLElement {
    connectedCallback() { this.innerHTML = `<p>Hello!</p>`; }
    }
    customElements.define('my-element', MyElement);
  • Use <my-element></my-element> in HTML.

  • Attach with:
    this.attachShadow({ mode: 'open' });
  • Encapsulates DOM & styles.

  • <template> for reusable markup.
  • <slot> for content projection.

  • Shadow Styles: Scoped inside shadow root.
  • Global vs Shadow: Global affects all; shadow is isolated.
  • CSS Variables:
    :host { color: var(--text-color, black); }

  • Update via JS:
    this.style.setProperty('--text-color', 'blue');

  • Attributes: Strings, observed via attributeChangedCallback.
  • Properties: Rich data types via JS.

  • Emit:
    this.dispatchEvent(new CustomEvent('my-event', { detail: data }));

  • Expose methods & properties on the class.

  • Internal state in fields.
  • Sync with attributes using setters/getters.

  • connectedCallback: Init.
  • disconnectedCallback: Cleanup.
  • attributeChangedCallback: React to changes.

  • Why: Reliability & maintainability.
  • Setup: Jest/Mocha + JSDOM.
  • Tests: Rendering, attributes, events.
  • Mocking: Isolate logic.
  • Debug: Interpret results, fix issues.

Great! Here’s the expanded teaching guide with detailed explanations and examples for each learning outcome. This will be structured for clarity and instructional use:


🌐 Vanilla Web Components: Detailed Teaching Guide

Section titled “🌐 Vanilla Web Components: Detailed Teaching Guide”

Explanation:
Web Components are a set of standardized APIs that allow developers to create reusable, encapsulated UI elements without relying on frameworks. They consist of:

  • Custom Elements: Define new HTML tags.
  • Shadow DOM: Encapsulate DOM and styles.
  • HTML Templates: Reusable markup.

Benefits:

  • Encapsulation: Prevents style and DOM conflicts.
  • Reusability: Components can be used across projects.
  • Framework Independence: Works in any modern browser.

Example:


Explanation:
Custom elements are created by extending HTMLElement and registering with customElements.define().

Example:

class MyButton extends HTMLElement {
connectedCallback() {
this.innerHTML = `<button>Click Me</button>`;
}
}
customElements.define('my-button', MyButton);

Explanation:
Shadow DOM isolates a component’s internal structure and styles from the global DOM.

Example:

class MyCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `<style>p { color: red; }</style><p>Hello!</p>`;
}
}
customElements.define('my-card', MyCard);

Explanation:
Templates provide reusable markup; slots allow dynamic content insertion.

Example:


Explanation:
Styles inside shadow root apply only to that component.

Example:

this.shadowRoot.innerHTML = `
<style>button { background: blue; color: white; }</style>
<button>Styled Button</button>
`;

  • Global styles: Affect entire page.
  • Shadow styles: Scoped to component.
  • Encapsulation: Prevents CSS conflicts.

Explanation:
Use --variables for external customization.

Example:

:host { color: var(--text-color, black); }

External page:

my-card { --text-color: green; }

Example:

this.style.setProperty('--text-color', 'blue');

Example:

static get observedAttributes() { return ['label']; }
attributeChangedCallback(name, oldVal, newVal) {
this.shadowRoot.querySelector('button').textContent = newVal;
}

Example:

this.dispatchEvent(new CustomEvent('clicked', { detail: { id: 1 } }));

Example:

class MyCounter extends HTMLElement {
increment() { this.count++; this.render(); }
}

  • Use internal fields for state.
  • Sync with attributes via setters/getters.
  • Update UI when state changes.

Example:

set count(val) { this._count = val; this.render(); }

  • connectedCallback: Init.
  • disconnectedCallback: Cleanup.
  • attributeChangedCallback: React to changes.

  • Why: Ensure reliability.
  • Setup: Jest/Mocha + JSDOM.
  • Tests: Rendering, attributes, events.
  • Mocking: Isolate logic.
  • Debug: Interpret results.

Example Test (Jest):

test('renders button', () => {
document.body.innerHTML = `<my-button></my-button>`;
expect(document.querySelector('button')).not.toBeNull();
});

Next Step:
Would you like me to compile this into a structured teaching document with headings, code blocks, and diagrams (PDF or DOCX), or create a slide deck for classroom presentation? Or both?