# 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 `