Element Types

Web ComponentsCustom Elements

  • autonomous custom elements: “all-new” elements, extending the abstract HTMLElement class.

  • customized built-in elements: extending built-in elements (such as <p>, <a>, <br>)

Autonomous

💾 replit.com

// ⭐️ 1. custom web component
class MyComponent extends HTMLElement {

    // constructor
    constructor() {

        // tell HTMLElement to initialize itself.
        super();

        // get `width`, `height` attributes
        const height = this.getAttribute('height') || '100px';
        const width = this.getAttribute('width') || '100px';

        // create <template> element
        const template = document.createElement('template');
        template.innerHTML = MyComponent.template(height, width);

        // add component to UI
        this.appendChild(document.importNode(template.content, true));
    }

    // template HTML
    static template(height, width) { 
        return ` 
            <style> 
                .placeholder { 
                    background-color: pink; 
                    width: ${height}; 
                    height: ${width}; 
                }
            </style>

            <div class='placeholder'>Placeholder</div>
        `;
    }
} 

// ⭐️ 2. custom tag <my-component>
// ⭐️⭐️ custom element names must contain a "hyphen".
customElements.define('my-component', MyComponent);

Customized Built-in Elments

// 1. extend built-in element 
class FancyButton extends HTMLButtonElement { 
    constructor(){...} 
}

// 2. register new tag
customElements.define('fancy-button', FancyButton, {extends: 'button'});

// 3. create with `document.createElement()`
let button = document.createElement('button', {is: 'fancy-button'});
button.textContent = 'Fancy button!';
button.disabled = true;
document.body.appendChild(button);

// 4. create with `new`
let button = new FancyButton();
button.textContent = 'Fancy button!';
button.disabled = true;

The required third parameter {extends: p} tells the browser which tag you're extending. This is necessary because many HTML tags share the same DOM interface.

  • <section>, <address>, and <em> (among others) all share HTMLElement.

  • both <q> and <blockquote> share HTMLQuoteElement, etc..

Specifying {extends: 'blockquote'} lets the browser know you're creating a souped-up <blockquote> instead of a <q>. 📘 Google ⟩ Extending native HTML elements

Last updated