# Web Components

Web Components are a suite of different technologies that allow you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps.

## 1. Three Main Technologies

1.  **Custom Elements:** A set of JavaScript APIs that allow you to define custom elements and their behavior.
2.  **Shadow DOM:** A set of JavaScript APIs for attaching an encapsulated "shadow" DOM tree to an element. This renders separately from the main document DOM.
3.  **HTML Templates:** The `<template>` and `<slot>` elements enable you to write markup templates that are not displayed in the rendered page until cloned.

## 2. Creating a Custom Element

To create a custom element, you create a class that extends `HTMLElement` (or a specific element like `HTMLButtonElement`).

```javascript
class MyButton extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = "<button>Click Me</button>";
  }
}

// Define the new element
customElements.define('my-button', MyButton);
```

**Usage in HTML:**
```html
<my-button></my-button>
```

## 3. Using Shadow DOM

Shadow DOM provides encapsulation for the JavaScript, CSS, and templating in a Web Component. Shadow DOM keeps the markup structure, style, and behavior hidden and separate from other code on the page so that different parts do not clash.

```javascript
class UserCard extends HTMLElement {
  constructor() {
    super();
    // Attach a shadow root to the element.
    const shadow = this.attachShadow({mode: 'open'});

    const wrapper = document.createElement('div');
    wrapper.setAttribute('class', 'wrapper');
    wrapper.innerText = "I am inside Shadow DOM";

    const style = document.createElement('style');
    style.textContent = '.wrapper { color: red; }'; // Only affects this component

    shadow.appendChild(style);
    shadow.appendChild(wrapper);
  }
}

customElements.define('user-card', UserCard);
```

## 4. Lifecycle Callbacks

Custom elements have special lifecycle callbacks:

*   `connectedCallback()`: Invoked when the custom element is first connected to the document's DOM.
*   `disconnectedCallback()`: Invoked when the custom element is disconnected from the document's DOM.
*   `attributeChangedCallback(name, oldValue, newValue)`: Invoked when one of the custom element's attributes is added, removed, or changed.

## 5. HTML Templates and Slots

You can define the structure in HTML using `<template>` and inject content using `<slot>`.

```html
<template id="my-template">
  <div class="card">
    <slot name="header">Default Header</slot>
  </div>
</template>
```

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/dom-manipulation]]