tezvyn:

Form-Associated Custom Elements: Your Own Inputs

AI-drafted, machine-checkedSource: html.spec.whatwg.orgadvanced

Make your custom elements behave like native inputs within a `<form>`. This lets them carry a value, be validated, and submit with the form. Use it for custom widgets like tag inputs. The footgun: its state won't submit if you don't call `setFormValue()`.

WHY IT EXISTS Before this, custom elements were second-class citizens in forms. You could build a fancy component, but it couldn't naturally participate in a <form>. You needed hidden inputs and JavaScript glue code to manage its value, validation, and submission. Form-associated custom elements were created to solve this, making custom components first-class form controls.

THE MENTAL MODEL Think of it as giving your custom element a "form-control soul." It's no longer just a visual widget; it's a participant in the form lifecycle. It can tell the form "this is my value" and "I am valid (or invalid)," and the form can disable it or reset it along with all the other native inputs, without any extra JavaScript glue.

HOW IT WORKS To make a custom element form-associated, you add a static property to its class: static formAssociated = true;. Then, in the element's constructor, you call this.attachInternals() to get an ElementInternals object. This object is the bridge to the parent form. You use its methods, like setFormValue() to set the submittable value and setValidity() to manage validation state. The browser handles the rest, including submission.

WHEN TO USE IT Use this whenever you're building a custom, interactive component that captures user data and needs to be part of a larger form. Examples include a custom color picker, a file uploader with a preview, a slider with custom ticks, or a complex address input with autocomplete. It simplifies form handling by eliminating manual synchronization with hidden inputs.

WHEN NOT TO USE IT Don't use this for purely presentational components that don't have a value to submit, like a custom-styled card or a decorative icon. If the element doesn't need to participate in form submission, validation, or state management (like being disabled or reset with the form), the extra complexity of ElementInternals is unnecessary. A standard autonomous custom element is sufficient.

ONE CANONICAL EXAMPLE To create a basic custom checkbox, you'd define a class extending HTMLElement and set static formAssociated = true;. In its constructor, you call this.attachInternals(). You would then add a click listener that toggles a checked state and, crucially, calls this.internals.setFormValue(this.checked ? 'on' : null). This ensures that when the form is submitted, the checkbox's state is included, just like a native <input type="checkbox">.

Read the original → html.spec.whatwg.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.