Learn to Code via Tutorials on Repl.it!

← Back to all posts
How To Make Custom HTML ELements!!!
lightningrock (147)

Custom HTML Elements

Hello! In this tutorial I'll be showing you how to make your own custom elements! There are two different kinds of custom HTML elements,

  • Autonomous custom elements - Elements that are simply custom
  • Customized built-in elements - Elements that are bassed on another HTML element.

Template For Custom HTML Elements

This is the template the you will be using for making custom HTML elements.

class MyElement extends HTMLElement {
  constructor() {
    // constructor code
  }

  connectedCallback() {
    // code to be called when element is added to document
  }

  disconnectedCallback() {
    // code to be called when element is removed from document
  }

  static get observedAttributes() {
    return []; // attributes to monitior for changes
  }

  attributeChangedCallback(name, oldValue, newValue) {
    // code to be called when attribute in the array above is changed
  }

  adoptedCallback() {
    /*
      code the be called when the element is moved into a new document
      this is done by document.adoptNode
      i wont be going over this since nobody really uses it
    */
  }

  // other methods and properties that you can define
}
customElements.define("my-element", MyElement); 
/*
  register the element, first parameter is the name to be used in the HTML document
  the example uses <my-element>
  the second parameter is class for the element
*/

Note:

The name of your custom element must contain a hyphen -, as my-element is valid, but myelement is not, to prevent name conflicts.

Autonomous custom elements

For this type of custom element, we might need a element that will serve as a time displayer. HTML already has a <time> element,
Example Of HTML time element
but it only lets you tell the browser that's it's a date, it doesn't do any formatting, and neither will it display the content in the datetime attribute! But we can do better than that! Here's a very basic code:

class CustomTimeElement extends HTMLElement {
  connectedCallback() {
    let date = new Date(this.getAttribute('datetime') || Date.now());

    this.innerHTML = new Intl.DateTimeFormat("default", {
      year: this.getAttribute('year') || undefined,
      month: this.getAttribute('month') || undefined,
      day: this.getAttribute('day') || undefined,
      hour: this.getAttribute('hour') || undefined,
      minute: this.getAttribute('minute') || undefined,
      second: this.getAttribute('second') || undefined,
      timeZoneName: this.getAttribute('time-zone-name') || undefined,
      timeZone: this.getAttribute('time-zone') || undefined,
      fractionalSecondDigits: this.getAttribute('fractional-seconds') || undefined,
      hour12: this.getAttribute('twelve-hour') || undefined
    }).format(date);
  }

}

customElements.define("custom-time-element", CustomTimeElement);

Then to use it:

<custom-time-element
  year="long"
  month="numeric"
  day="numeric"
  hour="short" 
></custom-time-element>

Example Of Custom HTML Element
What the connectedCallback() does is that it simply creates a date a sets the element's innerHTML to a formated version with the element's attributes.
Great! But the thing is, we need to keep updating the time when the attributes change! It isn't normal for a HTML element's attribute to be changed and the change not viewable! So let's fix that by using the observedAttributes() and attributeChangedCallback() functions.

class CustomTimeElement extends HTMLElement {
  render() {
    let date = new Date(this.getAttribute('datetime') || Date.now());
 
    this.innerHTML = new Intl.DateTimeFormat("default", {
      year: this.getAttribute('year') || undefined,
      month: this.getAttribute('month') || undefined,
      day: this.getAttribute('day') || undefined,
      hour: this.getAttribute('hour') || undefined,
      minute: this.getAttribute('minute') || undefined,
      second: this.getAttribute('second') || undefined,
      timeZoneName: this.getAttribute('time-zone-name') || undefined,
      timeZone: this.getAttribute('time-zone') || undefined,
      hour12: this.getAttribute('twelve-hour') || undefined
    }).format(date);
  }

  connectedCallback() {
    this.render()
  }

  static get observedAttributes() {
    return ['datetime', 'year', 'month', 'day', 'hour', 'minute', 'second', 'time-zone-name', 'time-zone', 'twelve-hour'];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this.render();
  }
}
 
customElements.define("custom-time-element", CustomTimeElement);

Example Of Custom HTML Element
Perfect! Now, if you want, you can add this little script

setInterval(() => document.getElementsByTagName[0].setAttribute('datetime', new Date()), 1000);

Which will update the time each second.
Example Of Custom HTML Element

Customized built-in elements

Now in the start I mentioned Customized built-in elements, which were just elements based off a element that already existed. For example, in our time element, the browser might like to know that this element was a time element, which we could do this:

class CustomTimeElement extends HTMLTimeElement {
  render() {
    let date = new Date(this.getAttribute('datetime') || Date.now());
 
    this.innerHTML = new Intl.DateTimeFormat("default", {
      year: this.getAttribute('year') || undefined,
      month: this.getAttribute('month') || undefined,
      day: this.getAttribute('day') || undefined,
      hour: this.getAttribute('hour') || undefined,
      minute: this.getAttribute('minute') || undefined,
      second: this.getAttribute('second') || undefined,
      timeZoneName: this.getAttribute('time-zone-name') || undefined,
      timeZone: this.getAttribute('time-zone') || undefined,
      hour12: this.getAttribute('twelve-hour') || undefined
    }).format(date);
  }

  connectedCallback() {
    this.render()
  }

  static get observedAttributes() {
    return ['datetime', 'year', 'month', 'day', 'hour', 'minute', 'second', 'time-zone-name', 'time-zone', 'twelve-hour'];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this.render();
  }
}
 
customElements.define("custom-time-element", CustomTimeElement);

Example Of Custom HTML Element
This might be usefull for accessibility, screen readers, and other things like this, and I suggest you should try to do this whenever possible.

Why custom elements?

wHy Sh0uLd y0U usE custom elements? Well do you know div soup? No? Well put simply, it's just a TON of nested divs. For example which one do you like better?

<user-feed>
  <user-feed-recomendation>
    <post>
      <post-author-profile>
        <post-author-avatar src="https://images.site.com/user/avatar/18789.png">
        </post-author-avatar>
        <post-author-name>
          John Doe
        </post-author-name>
      </post-author-profile>
      <post-content>
        <post-vote>
          <upvote-button>
            Upvote!
          </upvote-button>
          <downvote-button>
            Downvote!
          </downvote-button>
          <post-votes>17</post-votes>
        </post-vote>
        <post-question>
          Hello! I'm new to python, and can somebody show me how to make use if?
        </post-question>
        <post-answers>
          <post-answer>
            <answer-vote>
              <upvote-button>
                Upvote!
              </upvote-button>
              <downvote-button>
               Downvote!
              </downvote-button>
              <answer-votes>8</answer-votes>
            </answer-vote>
            <answer-content>
              Try this:
              if condition == true:
                #do something
            </answer-content>
          </post-answer>
        </post-answers>
      </post-content>
    </post>
  </user-feed-recomendation>
</user-feed>

OR

<div id="feed">
  <div id="recomended">
    <div class="post">
      <div class="author">
        <img src="https://images.site.com/user/avatar/18789.png">
        </img>
        <p id="author-name">
          John Doe
        </p>
      </div>
      <div class="post-content">
        <div class="post-vote">
          <button onclick="vote('up')">
            Upvote!
          </button>
          <button>
            Downvote!
          </button onclick="vote('up')">
          <p class="votes">17</p>
        </div>
        <div class="question">
          Hello! I'm new to python, and can somebody show me how to make use if?
        </div>
        <div class="answers">
          <div class="answer">
            <div class="answer-vote">
              <button onclick="vote('up')">
                Upvote!
              </button>
              <button>
                Downvote!
              </button onclick="vote('up')">
              <p class="votes">8</p>
            </div>
            <p class="post-answer">
              Try this:
              if condition == true:
                #do something
            </p>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Probably the first one right? It's a ton better than the second one with div soup and no custom elements. So that's why you should try to use custom elements.

Thanks for reading my tutorial! I hoped you learned something new!

@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock
@lightningrock @lightningrock @lightningrock @lightningrock

self pings for no reason cuz im bored

Link To Post