Defining Elements with customElements.define
Register a custom element class with the browser.
Defining Elements with customElements.define is a free HTML Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Are Custom Elements?
Custom elements let you invent your own HTML tags backed by a JavaScript class. Once defined, <my-card> behaves like any built-in element: it can be written in HTML, queried, styled, scripted, and used inside frameworks unchanged.
The Hyphen Requirement
Every custom element name must include at least one hyphen — user-avatar, app-button, my-card. The hyphen distinguishes custom elements from current and future built-in HTML tags and is enforced by the spec.
Defining a Class
A custom element is a class that extends HTMLElement (or a built-in subclass). The class can declare a constructor and lifecycle callbacks. Public properties and methods on the class become the element's scripting interface.
class MyCard extends HTMLElement {
constructor() {
super();
this.textContent = "Hello from MyCard";
}
}Registering with define
customElements.define("my-card", MyCard) registers the class under the tag name. After registration, every existing and future <my-card> in the document is upgraded into an instance of the class.
super() is Mandatory
The constructor must call super() as its first statement before touching this. Skipping super() throws "Failed to construct 'HTMLElement'". Treat it like the standard JavaScript class constructor rule that it is.
No DOM Reads in constructor
The constructor may not read the element's attributes or children — they may not be parsed yet at construction time. Move DOM-touching setup into connectedCallback, which fires only after the element is in the document.
Registration is Permanent
An element name can be registered only once per page. Re-defining the same name throws a NotSupportedError. Reload the page to test changes during development; in production, register each component once at startup.
Polyfills
Custom elements ship in every modern browser. For very old browsers (mostly defunct), the webcomponents.js polyfill provides a fallback. New projects can ship native and skip the polyfill entirely.
Detecting Definition Status
customElements.get("my-card") returns the class if defined, undefined otherwise. customElements.whenDefined("my-card") returns a promise that resolves once the element is registered — useful for code that needs to wait for late-loaded definitions.
customElements.whenDefined("my-card").then((Class) => {
console.log("MyCard is ready");
});Using the Element
Once defined, use the element exactly like a built-in tag: write it in HTML (<my-card></my-card>), create it via document.createElement("my-card"), or instantiate via new MyCard() and insert. All three paths produce the same upgraded instance.
Naming Conventions
Prefix custom elements with a project or company name (cd-card, app-modal) to avoid collisions with other libraries on the same page. The web component ecosystem is unbundled — anyone on your page can register any name, and the first registration wins.
Knowledge Check
Why must every custom element name contain a hyphen?
Summary
Custom elements are JavaScript classes extending HTMLElement, registered via customElements.define("name", Class) where the name must contain a hyphen. The constructor must call super() first and must not read the DOM; defer DOM work to connectedCallback. Defined elements behave exactly like built-in tags everywhere.
Frequently asked questions
Is the “Defining Elements with customElements.define” lesson free?
Yes — the full text of “Defining Elements with customElements.define” is free to read here on the web, and the HTML Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the HTML Academy course, upgrade to CoddyKit PRO.
What will I learn in “Defining Elements with customElements.define”?
Register a custom element class with the browser. You practise HTML Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start HTML Academy?
No prior experience is required. HTML Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Defining Elements with customElements.define” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this HTML Academy lesson?
Yes. Every HTML Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining Elements with customElements.define
- The connectedCallback and disconnectedCallback
- Observed Attributes and attributeChangedCallback
- Extending Built-in Elements