# Custom elements We can create custom HTML elements, described by our class, with its own methods and properties, events and so on. Once a custom element is defined, we can use it on par with built-in HTML elements. That's great, as HTML dictionary is rich, but not infinite. There are no ``, ``, ``... Just think of any other tag we might need. We can define them with a special class, and then use as if they were always a part of HTML. There are two kinds of custom elements: 1. **Autonomous custom elements** -- "all-new" elements, extending the abstract `HTMLElement` class. 2. **Customized built-in elements** -- extending built-in elements, like a customized button, based on `HTMLButtonElement` etc. First we'll cover autonomous elements, and then move to customized built-in ones. To create a custom element, we need to tell the browser several details about it: how to show it, what to do when the element is added or removed to page, etc. That's done by making a class with special methods. That's easy, as there are only few methods, and all of them are optional. Here's a sketch with the full list: ```js class MyElement extends HTMLElement { constructor() { super(); // element created } connectedCallback() { // browser calls this method when the element is added to the document // (can be called many times if an element is repeatedly added/removed) } disconnectedCallback() { // browser calls this method when the element is removed from the document // (can be called many times if an element is repeatedly added/removed) } static get observedAttributes() { return [/* array of attribute names to monitor for changes */]; } attributeChangedCallback(name, oldValue, newValue) { // called when one of attributes listed above is modified } adoptedCallback() { // called when the element is moved to a new document // (happens in document.adoptNode, very rarely used) } // there can be other element methods and properties } ``` After that, we need to register the element: ```js // let the browser know that is served by our new class customElements.define("my-element", MyElement); ``` Now for any HTML elements with tag ``, an instance of `MyElement` is created, and the aforementioned methods are called. We also can `document.createElement('my-element')` in JavaScript. ```smart header="Custom element name must contain a hyphen `-`" Custom element name must have a hyphen `-`, e.g. `my-element` and `super-button` are valid names, but `myelement` is not. That's to ensure that there are no name conflicts between built-in and custom HTML elements. ``` ## Example: "time-formatted" For example, there already exists `