Web Foundations

Custom Elements

Defining custom HTML elements, lifecycle callbacks, and encapsulation.

Advertisement

Custom Elements

Defining custom HTML elements, lifecycle callbacks, and encapsulation.

Overview

Custom elements extend HTML with new tags.

Key Concepts

  • CustomElementRegistry — Register new elements
  • Lifecycle Callbacks — connected, disconnected, attribute changed
  • Shadow DOM — Encapsulation
  • Templates — Reusable markup
  • Framework Agnostic — Work anywhere

Code Examples

<user-card name="John Doe" email="john@example.com" avatar="https://i.pravatar.cc/150?u=john">
</user-card>

<user-card name="Jane Smith" email="jane@example.com">
</user-card>

<script>
class UserCard extends HTMLElement {
  static get observedAttributes() {
    return ['name', 'email', 'avatar'];
  }

  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  connectedCallback() {
    this.render();
  }

  attributeChangedCallback() {
    this.render();
  }

  render() {
    const name = this.getAttribute('name') || 'Unknown';
    const email = this.getAttribute('email') || '';
    const avatar = this.getAttribute('avatar') || `https://ui-avatars.com/api/?name=${encodeURIComponent(name)}`;

    this.shadowRoot.innerHTML = `
      <style>
        :host {
          display: flex;
          align-items: center;
          padding: 16px;
          border: 1px solid #ddd;
          border-radius: 8px;
          margin: 8px 0;
          font-family: system-ui, sans-serif;
        }
        .avatar {
          width: 60px;
          height: 60px;
          border-radius: 50%;
          margin-right: 16px;
        }
        .info h3 {
          margin: 0 0 4px 0;
          font-size: 1.2rem;
        }
        .info p {
          margin: 0;
          color: #666;
        }
      </style>
      <img class="avatar" src="${avatar}" alt="${name}">
      <div class="info">
        <h3>${name}</h3>
        <p>${email}</p>
      </div>
    `;
  }
}

customElements.define('user-card', UserCard);
</script>

Practice

Create a custom <notification-toast> element with auto-dismiss.

Advertisement