is
Extend native HTML elements with custom behavior via customized built-in elements. Inherits all native semantics, accessibility, and form participation for free.
Overview
The is attribute creates customized built-in elements — native HTML elements enhanced with custom JavaScript behavior. Unlike autonomous custom elements (e.g., <my-component>), customized built-ins inherit all native behavior: semantics, accessibility, form participation, and default styles.
The syntax is <element is="custom-name">, where the custom element class extends the native element's interface (e.g., HTMLButtonElement, HTMLInputElement).
Usage
Add the is attribute to a native element to activate the custom behavior registered for that name.
<!-- Use a customized built-in button --><button is="confirm-button">Delete Account</button> <!-- The element is still a <button> with all native behavior: - Form participation - Keyboard activation (Enter/Space) - Default button styling - Screen reader announces "button" But with custom behavior added by the class -->
Registration
The custom element class must extend the specific element interface, and the define() call must include the extends option.
<script>class ConfirmButton extends HTMLButtonElement { connectedCallback() { this.addEventListener('click', (e) => { if (!confirm(`Are you sure you want to: ${this.textContent}?`)) { e.preventDefault(); e.stopPropagation(); } }); }} // Third argument { extends } tells the registry which element is being extendedcustomElements.define('confirm-button', ConfirmButton, { extends: 'button' });</script>
Example: Auto-Format Input
A text input that automatically formats phone numbers as the user types. It inherits all native input behavior — form submission, validation, labels, autofill.
<script>class AutoFormatInput extends HTMLInputElement { connectedCallback() { this.addEventListener('input', () => { // Auto-format as phone number: (123) 456-7890 const digits = this.value.replace(/\D/g, '').slice(0, 10); if (digits.length >= 6) { this.value = `(${digits.slice(0,3)}) ${digits.slice(3,6)}-${digits.slice(6)}`; } else if (digits.length >= 3) { this.value = `(${digits.slice(0,3)}) ${digits.slice(3)}`; } }); }} customElements.define('auto-format-input', AutoFormatInput, { extends: 'input' });</script> <label for="phone">Phone</label><input is="auto-format-input" type="tel" id="phone" name="phone" />
Customized vs Autonomous
There are two types of custom elements. The is attribute is for the customized built-in type.
<!-- Customized built-in: extends <button>, inherits everything --><button is="fancy-button">Click Me</button> <!-- Autonomous custom element: starts from scratch --><fancy-button>Click Me</fancy-button>
| Feature | Customized Built-in (is) | Autonomous (<my-el>) |
|---|---|---|
| Syntax | <button is="x"> | <my-button> |
| Extends | Specific element interface | HTMLElement |
| Native semantics | Inherited | Must be added manually |
| Form participation | Inherited | Requires ElementInternals |
| Default styles | Inherited | None |
| Safari support | No | Yes |
| Browser support | Chrome, Firefox, Edge | All modern browsers |
Accessibility
- The primary advantage of customized built-in elements is accessibility. A
<button is="fancy-button">is announced as "button" by screen readers, participates in tab order, and responds to Enter and Space — with zero extra work. - An autonomous
<fancy-button>would needrole="button",tabindex="0", and keyboard event handlers to achieve the same accessibility. - For form controls, the
isapproach inherits native validation, labels, and error messages automatically.
Limitations
- Safari does not support the
isattribute. This is the most significant limitation. Safari's WebKit team has explicitly declined to implement it, citing architectural concerns. This makes customized built-ins unreliable for production use without a polyfill. - A polyfill exists but adds bundle size and complexity. It works by detecting
isattributes and manually upgrading elements. - Each customized built-in can only extend one specific element type. A class extending
HTMLButtonElementcannot be used on an<input>. - Server-rendered HTML with
isattributes works in Chrome and Firefox before JavaScript loads (the native element renders normally). In Safari, theisattribute is simply ignored. - Due to the Safari limitation, the web platform has largely moved toward autonomous custom elements instead. Most component libraries use
<my-element>syntax for universal compatibility.
See Also
- Web Components — VB's custom elements (using autonomous syntax for browser compatibility)
tabindex— manage focus order for custom interactive elementsdisabled— inherited by customized built-in form controls