When designing a custom element, we try to mimic how a native HTML element behaves. For example, a form participating custom element should have a
value content and IDL attribute.
Our general philosophy of striving for progressive enhancement extends to custom elements as well. We keep as much of the content in markup as possible and only add behaviors on top of that. For example,
<local-time> shows the raw timestamp by default and gets upgraded to translate the time to the local timezone, while
<details-dialog>, when nested in the
Being dependent on markup also means we avoid reinventing the wheel wherever possible. We should never be re-implementing
<input> from scratch; instead, we depend on
<input> and use a custom element wrapper to add behaviors. See
<auto-complete> for an example.
We have a boilerplate for custom elements, which includes build steps, tests, demo pages, and linters.
connectedCallback is invoked each time the Custom Element is appended into a document-connected element. This will happen each time the node is moved, and may happen before the element's contents have been fully parsed. (from MDN)
If your element depends on its child elements heavily, consider using
This behaves correctly in Chrome but not in Firefox & Safari where
connectedCallback is fired when DOM contents are partially parsed depending on load speed. More discussions here:
- Chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=821831
- Safari: https://bugs.webkit.org/show_bug.cgi?id=183931
- Discussions on lack of child change callbacks: w3c/webcomponents#550, w3c/webcomponents#619, whatwg/dom#662
We do not use Shadow DOM because:
- Full Shadow DOM polyfill is not feasible as it requires very invasive override of native DOM APIs.
- Shady DOM has serious performance issues. The native
querySelectorAllas well as many other native DOM APIs are patched so Shadow Root elements can be queried correctly, but it's extremely slow.
- There is no server side rendering support on the horizon yet. Potential solutions are still being discussed. See: Declarative Shadow DOM, Declarative Syntax for Custom Elements.