HTML Academy · Lesson

Extending Built-in Elements

Customize existing elements with the is attribute.

Lesson 4 of 413 steps

Extending Built-in Elements is a free HTML Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the HTML Academy learning path, and your progress syncs across the web and the CoddyKit app. The HTML Academy course includes 4 lessons in total.

Two Kinds of Custom Elements

The spec defines autonomous custom elements (extending HTMLElement, used as <my-card>) and customized built-in elements (extending a specific built-in class, used as <button is="my-button">). Customized built-ins inherit built-in semantics for free.

Why Extend a Built-in?

Autonomous <my-button> gets none of the built-in <button> behavior — no Enter/Space activation, no form participation, no role="button" for assistive tech. A customized button (is="my-button") inherits all of that automatically.

Extending the Class

Extend the specific HTML class instead of HTMLElement: class MyButton extends HTMLButtonElement {}. The element keeps all built-in behavior — form submission, focus management, disabled state — and you add your enhancements on top.

class MyButton extends HTMLButtonElement {
  connectedCallback() {
    this.style.fontWeight = "bold";
  }
}

Registering with the extends Option

customElements.define("my-button", MyButton, { extends: "button" }). The third argument tells the registry which built-in tag the element extends. Without it, the registration throws.

The is Attribute

Use customized built-ins with the is attribute on the existing tag: <button is="my-button">Click</button>. Writing <my-button> instead would create an autonomous element and lose the built-in behavior.

Safari Does Not Support It

Safari has refused to implement customized built-in elements citing accessibility concerns. They work in Chrome, Edge and Firefox; in Safari the is attribute is ignored and the element behaves as a plain <button>. Use the official polyfill when Safari support is required.

Polyfill Options

The @ungap/custom-elements polyfill restores customized built-in support in Safari. It is small and well-maintained; include it when your team needs cross-browser support without abandoning the is-attribute pattern.

Autonomous Alternative

If Safari without a polyfill matters, build an autonomous element instead and manually replicate the needed behavior: add role="button", tabindex="0", keyboard handlers for Enter/Space, and form-association via the ElementInternals API.

Form Association API

Autonomous elements can participate in form submission by setting static formAssociated = true and using this.attachInternals(). The returned ElementInternals object provides setFormValue and setValidity for full form integration.

When to Choose Which

Choose customized built-ins for components that mostly behave like a built-in element (a fancy button, a smart input) and your platform support is Chrome/Firefox or you tolerate the polyfill. Choose autonomous for entirely new components (cards, dialogs) with no built-in equivalent.

Pitfall: Autonomous Buttons

The most common web-components mistake is creating <my-button> as an autonomous element. It will not submit forms, will not respond to Enter/Space, and will not be announced as a button. Either extend HTMLButtonElement or carefully replicate every behavior of a real button.

Knowledge Check

What is the practical advantage of extending HTMLButtonElement (customized built-in) over extending HTMLElement (autonomous) for a button-like component?

Summary

Customized built-in elements extend a specific HTML class (HTMLButtonElement, HTMLInputElement) and are used via the is attribute, inheriting all native behavior. Register with the { extends: "button" } option. Safari does not support them natively — polyfill or use autonomous elements with manual behavior replication when full cross-browser support is required.

Free to start

Learn HTML with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
40
Lessons
159

Frequently Asked Questions

Is the “Extending Built-in Elements” lesson free?

Yes — any 3 lessons of the HTML Academy learning path, including “Extending Built-in Elements”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The HTML Academy course includes 4 lessons in total.

What will I learn in “Extending Built-in Elements”?

Customize existing elements with the is attribute. 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, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Extending Built-in Elements” 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

  1. Defining Elements with customElements.define
  2. The connectedCallback and disconnectedCallback
  3. Observed Attributes and attributeChangedCallback
  4. Extending Built-in Elements
← Back to HTML Academy