CodeBlanks Logo Icon CodeBlanks

Challenge - Custom element

JavaScript course · Advanced · Lesson 100/100

Build a component structure with custom elements and shadow DOM.

Custom element

In this challenge you will write a custom element: the <bookmark-card> tag. First you define a class that extends HTMLElement.

To register it you call customElements.define('bookmark-card', BookmarkCard). The first argument is the tag name and must contain a hyphen.

Among the lifecycle callbacks, connectedCallback fires when the element is attached to the document. Here you open a shadow root with this.attachShadow({ mode: 'open' }) and write the content into it, keeping styles from leaking out.

Shadow DOM and lifecycle

To isolate a custom element's content from the outside you use shadow DOM. this.attachShadow({ mode: 'open' }) attaches a shadow root to the element.

You write HTML into the returned shadow root's innerHTML; this content stays separate from the outer document and does not leak styles.

connectedCallback is a lifecycle callback: it runs every time the element is added to the DOM. Opening the shadow root and writing the content here is the most common pattern.

Exercise Write the BookmarkCard element

Write a BookmarkCard class that extends HTMLElement and has a connectedCallback method. Inside it open a shadow root with this.attachShadow({ mode: 'open' }) and write a paragraph into its innerHTML. Then register it with customElements.define('bookmark-card', BookmarkCard).

Show example solution
'open' }) and set shadow.innerHTML. At the end add customElements.define('bookmark-card', BookmarkCard);.

Example solution:
class BookmarkCard extends HTMLElement {
  connectedCallback() {
    const shadow = this.attachShadow({ mode: 'open' });
    shadow.innerHTML = '<p>Bookmark</p>';
  }
}
customElements.define('bookmark-card', BookmarkCard);

Test yourself

  1. How do you register a custom element?

    customElements.define('bookmark-card', BookmarkCard);
    • document.registerElement
    • customElements.define
    • window.defineElement
    • HTMLElement.register
    Show answer

    customElements.define — Correct! customElements.define takes the tag name and the class.

  2. Register the element

    class BookmarkCard extends HTMLElement {
      constructor() {
        super();
      }
    }
    ____;
    Show answer
    class BookmarkCard extends HTMLElement {
      constructor() {
        super();
      }
    }
    customElements.define('bookmark-card', BookmarkCard);

All lessons in Advanced