Extending Built-in Elements
Customize existing elements with the is attribute.
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.
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
- Defining Elements with customElements.define
- The connectedCallback and disconnectedCallback
- Observed Attributes and attributeChangedCallback
- Extending Built-in Elements