A user account is required in order to edit this wiki, but we've had to disable public user registrations due to spam.

To request an account, ask an autoconfirmed user on Chat (such as one of these permanent autoconfirmed members).

Custom Elements

From WHATWG Wiki
Revision as of 12:50, 6 July 2016 by Domenic (talk | contribs) (Reverted edits by Annevk (talk) to last revision by Dglazkov)
Jump to navigation Jump to search

This page documents open technical issues with Custom Elements based on [email protected] from January to March 2015.

Rough consensus

There appears to be rough consensus for:

  • ES6-style classes (Spec/Chrome: mutating prototype)
  • Subclassing of HTMLElement and SVGElement
  • An API to tie a class to a local name (e.g. registerElement())
  • Lifecycle callbacks for: insertion into a document, removal from a document, mutation of an attribute

Additional lifecycle callbacks

There's a proposal in various bugs to offer these lifecycle callbacks as well:

  • Adopting so when moving nodes across documents adjustments can be made (e.g. an <img> has its animation restarted). This callback needs to be passed the old and new document.
  • Cloning so cloneNode() can have similar semantics for custom elements as it does for e.g. <input>. For cloning we want the browser to create a clone (via the constructor) and copy all content attributes. Then the callback is passed the clone, a document, and the clone children flag (note that these are only needed for children not part of a tree, for elements such as <template>, children part of the tree are handled by the browser).

Use symbols to identify lifecycle callbacks

It has been suggested that we should use symbols rather than names ending in Callback to avoid collisions with libraries.


Upgrading is the concept of going from a piece of markup, such as <my-div data-teehee="💩"></my-div>, to an object in a tree.

Tactic Explanation Drawbacks
Spec/Chrome A basic element is created by the parser and then its prototype is mutated at a later stage followed by a callback.
  • Does not use ES6-style classes
  • Does not have identity at all (at best it looks alike due to the mutated prototype)
Brain transplant ("Dmitry") A basic element is created by the parser and a callback registered by the developer is invoked at a later point to turn that basic element into a custom element.
  • Not having identity at creation-time is currently a mismatch with the rest of the platform. (Domenic suggests we could maybe change the rest of the platform.)
Dummy replacement A dummy element is created by the parser and replaced at a later point by an actual instance of the custom element created by invoking the constructor registered by the developer.
  • What about attributes on the dummy element?
  • What about event listeners on the dummy element?
  • What if the dummy element was removed from the tree (or moved around)?
  • Causes mutation observer "spam"
Synchronous constructor The constructor registered by the developer is invoked by the parser at the point the custom element is created and inserted into the tree.
  • Requires synchronization for document.write() for each custom element.
  • Nested event loop.
  • Does not work with asynchronously loaded assets.
  • Unclear how it works with cloning.
Almost-synchronous constructor ("Jonas") The parser does bookkeeping of where custom elements need to be inserted and does it at a later synchronization point.
  • Potential performance issues.
  • Complicated?
  • Unclear how it works with cloning.

(Written under the assumption that mutating the prototype of the basic element is no longer considered viable.)

Subclassing existing elements

Subclassing existing elements is hard as implementation-wise identity is both object-based and name / namespace based. Therefore subclassing an existing element (currently) requires that the name / namespace does not change.

A hack was invented to make this work: <button is="my-button">. That hack is not well liked leaving us two options:

  • We leave this for now and work on this in parallel while stabilizing a smaller subset of custom elements.
  • We block on this and delay even more.

However, without this hack accessibility for trivial components is harder as more things have to be done by hand.

(Assuming that not all implementers are suddenly going to be okay with this hack.)

Another use case had emerged for the "is" hack: piggy-backing on parser behaviors. For example, extending <template> for data binding or as a way to specify shadow trees in HTML.

ARIA integration