Skip to content
On this page

How to use ElementInternals

INFO

ElementInternals is Chrome-only but are under development in Safari.

ElementInternals allows custom elements to get the full feature set of form elements (labelling, validation, ARIA behaviors).

Example

html
<form id="myForm">
  <custom-checkbox id="custom-checkbox"></custom-checkbox>
  <custom-label for="custom-checkbox">Join newsletter</custom-label>
</form>
<form id="myForm">
  <custom-checkbox id="custom-checkbox"></custom-checkbox>
  <custom-label for="custom-checkbox">Join newsletter</custom-label>
</form>
js
class CustomCheckbox extends HTMLElement {
  static formAssociated = true;

  constructor() {
    super();
    this._internals = this.attachInternals();
  }

  connectedCallback() {
    console.log(this._internals.form.length)
  }
}

window.customElements.define("custom-checkbox", CustomCheckbox);
class CustomCheckbox extends HTMLElement {
  static formAssociated = true;

  constructor() {
    super();
    this._internals = this.attachInternals();
  }

  connectedCallback() {
    console.log(this._internals.form.length)
  }
}

window.customElements.define("custom-checkbox", CustomCheckbox);

After you attach ElementInternals and set formAssociated to true, your element gets new form-based superpowers ✨

js
// Form controls usually expose a "value" property
get value() { return this.#value; }
set value(v) { this.#value = v; }

// The following properties and methods aren't strictly required,
// but browser-level form controls provide them. Providing them helps
// ensure consistency with browser-provided controls.
get form() { return this._internals.form; }
get name() { return this.getAttribute('name'); }
get type() { return this.localName; }
get validity() {return this._internals.validity; }
get validationMessage() {return this._internals.validationMessage; }
get willValidate() {return this._internals.willValidate; }

checkValidity() { return this._internals.checkValidity(); }
reportValidity() {return this._internals.reportValidity(); }
// Form controls usually expose a "value" property
get value() { return this.#value; }
set value(v) { this.#value = v; }

// The following properties and methods aren't strictly required,
// but browser-level form controls provide them. Providing them helps
// ensure consistency with browser-provided controls.
get form() { return this._internals.form; }
get name() { return this.getAttribute('name'); }
get type() { return this.localName; }
get validity() {return this._internals.validity; }
get validationMessage() {return this._internals.validationMessage; }
get willValidate() {return this._internals.willValidate; }

checkValidity() { return this._internals.checkValidity(); }
reportValidity() {return this._internals.reportValidity(); }

/via MDN

Resources

Licenced MIT