# Custom elements
We can create custom HTML elements, described by our class, with its own methods and properties, events and so on.
Once an 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 customized `HTMLButtonElement` etc.
First we'll create autonomous elements, and then 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 it when the element is added to the document
// (can be called many times if an element is repeatedly added/removed)
}
disconnectedCallback() {
// browser calls it 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 `