#244: HTML General Review: Custom Elements

Visit on Github.

Opened Apr 17, 2018

Hello TAG!

This issue is part of the TAG's larger effort to review the HTML spec in its entirety--please see the original issue https://github.com/w3ctag/design-reviews/issues/174 for a summary of all the break-out issues.

The "Sections" are all the sections of the WHATWG HTML spec that should be reviewed as part of this issue. Where the spec section has associated Web Platform Tests, the specific WPT path is noted. While the primary focus of the review is the specification text, it can be helpful to review the related tests to help clarify algorithms or see interoperability conformance issues (or find issues with the tests).

The "Features" are just a sample of what you will encounter as part of this spec section, it's not meant to be exhaustive.

Here are some example suggestions for what to look for during the review, but don't limit to only these suggestions!

  • Look for any APIs that could be 'modernized' according to current design practices.
  • Look for things that could require permissions that aren't modelled in the permissions API at the moment.
  • Look for areas of the platform that contain UA 'magic' (aren't possible for JavaScript programs to emulate due to missing primitives in the platform). These are candidates for future Extensible Web archeology.
  • Look for areas of the spec that describe "wishful thinking" (e.g., that describe a feature that is implemented by no one). Such features should at least have implementor commitments, or they might be candidates for removal from the spec.
  • Look for cryptic and hard-to-follow algorithms that could be improved with extra explanatory text or improved prose. E.g., sometimes adding a "developer note" (green box) can add the needed clarity to understand the intent/purpose or outcome of a complex concept.
  • Look for concepts that are meant to be used together, but where this is not spelled out or explained clearly
Sections WPT path Features
3.2.3 custom-elements/htmlconstructor
4.13 custom-elements <my-element>

Please provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify [github usernames]

Discussions

Comment by @chaals Jun 19, 2018 (See Github)

This is a request for a review of the specific question "what attribute names should be valid for custom elements".

In WHATWG it depends on whether they are customised built-in elements or autonomous custom elements, but in the W3C HTML spec it makes no distinction and restricts custom attribute names to be in the data- space (for authors).

The relevant issues are https://github.com/w3c/html/issues/1337 and https://github.com/whatwg/html/issues/2271

Discussed Aug 21, 2018 (See Github)

KC: It's shipping... Some feedback around the term callback suffix on all the APIs.

AR: Additional areas of feedback:

  • Lack of integration with forms (prevents ability to have custom input type)--we can encourage them to address this in the future.
  • Synchronous upgrades
  • Sub-registries - large apps would like to scope custom-elements to certain parts of the tree.

PL: Q from chaals about what attribute names should be valid for CE?

DB: WHATWG and W3C specs disagree.

AR: How do they differ?

DB: particular attribute names.

SM: Might be WHATWG has restriction on what names are allowed, but implementations don't follow that? (W3C doesn't have the restriction?)

AR: I wouldn't use CE if I had to prefix. Yuck. CE authors define their attributes locally (to the element).

TL: Is there a conflict with a future "custom attribute"?

AR: Potential issue is whether some new global attribute creates a new processing model for something that wasn't defined before.

PL: Imagine a new 'class' or 'id' global attribute that gets introduced later... the system for processing this might override or have a side effect that is unexpected. Only safe path here is to prefix custom element's attributes.

AR: ...or you have to exembpt custom elements from the processing logic.

PL: like providing a way for the system to query for a custom attribute without conflict.

AR: or have a way of opt-ing the attributes in/out of the global processing. We probably can't have a opt-in, but maybe and opt-out?

AR: Prefixing is a pain and probably web-incompatible at this point. So, we can't recommend this, but we can recommend a way to add defensiveness to the custom-element iatnstead.

Comment by @slightlyoff Aug 21, 2018 (See Github)

Hey all,

Thanks for the links to the relevant discussion, @chaals. Spirited!

We had a pretty long conversation about this in today's call.

In general, it seems we're constrained in our ability to provide guidance as this horse has been out of the barn for a few years. We don't have strong data for potential collision as-yet, but the TAG will be sure to encourage feature designers proposing new attributes to collect that sort of data to look for conflicts in future.

Anecdotally, it seems many element authors are going without prefixes. Here's a random set from webcomponents.org that include attributes:

The core issue is that the platform acts like a framework for running elements in a lifecycle they do not fully control, potentially processing attributes "behind" the back of a custom element. @plinss brings up the case of something like style or class which is processed in a high-frequency way. If a newskoolstyle global attribute were added and if it affected style or layout, and if a custom element already used such a value using a syntax that was somehow compatible (likely for booleans), the system may choose to do things the element author didn't want or anticipate.

Prefixing is one solution, ensuring that developers tell the system "don't use this, it's not for you", but it doesn't appear we'll be able to normatively restrict unprefixed attributes at this late date.

Other solutions are less complete. One could imagine a method which Custom Elements can invoke from their constructors to inform the system about "owned" attributes, preventing the system from using them for internal processing, treating them as "inert". Used defensively this would keep new HTML additions from breaking existing behavior. There's a fly in this ointment with regards to un-upgraded elements and it isn't clear what to do in those cases.

The best advice that we feel we can currently give is that HTML spec editors should only add global, side-effecting attributes after extensive study of the ecosystem to minimize breakage. Prefixing does not seem possible, but data would be a valuable contribution.

/cc @LeaVerou @annevk @domenic

Comment by @annevk Aug 22, 2018 (See Github)

Yeah, I think that's what we roughly concluded as well, though with these caveats:

  1. Encouraging prefixing might still be worthwhile, especially for frameworks that might be used behind closed doors and end up being excluded from studies.
  2. If we add "custom global attributes", effectively callbacks for global attribute manipulation (and somewhat analogous to custom elements), we could require those to have a prefix (and probably need to, to avoid breakage and collisions).
Comment by @slightlyoff Sep 11, 2018 (See Github)

I like the idea of adding prefixing for "custom global attributes"; perhaps using the same restriction as we have today on element names?

Per today's F2F, we're going to close this out with the conclusion that prefixing isn't possible at this late date and hope the discussion here can serve as a set of ideas to be mined/cited in future should partial solutions become necessary.

/cc @chaals @annevk

Comment by @chaals Sep 11, 2018 (See Github)

@slightlyoff if we punt the problem completely now, doesn't that increase the likelihood that at any time we want to introduce it for custom attributes later we will find it more difficult?

That was the rationale for W3C HTML to require data-* for now, although developers don't really want those extra 5 characters... We know there are plenty of non-conformant attributes out there, but not sending a clear signal asking to reduce that seemed like we would be unhappier later...

Comment by @travisleithead Sep 11, 2018 (See Github)

doesn't that increase the likelihood that at any time we want to introduce it for custom attributes later we will find it more difficult?

@chaals see annevk's comment about "custom global attributes" above -- where those would likely require a hyphen to avoid conflicting with known attributes (just like custom elements requires today). So, I don't think we need to worry about future conflicts with custom attributes. As noted above, new built-in attributes will need to be added with care.

Comment by @LeaVerou Sep 11, 2018 (See Github)

That was the rationale for W3C HTML to require data-* for now, although developers don't really want those extra 5 characters...

This is misrepresenting developer concerns a tad. Developers are fine with these 5 extra characters in many cases. When it's a small library with few attributes used in few places, data-* is fine. However, with multiple attributes used all over the place, data- adds clutter and actually hinders readability, as these repetitive prefixes must be cognitively ignored. Furthermore, when it's many attributes, namespacing of some sort is needed to indicate which attributes belong to the library/framework/language and which don't (e.g. v-, ng-, mv- etc) and prevent clashes. If data- is ALSO required, it's not 5 characters any more, it's considerably more than 50% of the length of the attribute!

Furthermore, often custom elements require the addition of new global attributes or attributes on existing, non-custom elements. For example, imagine <datalist> implemented as a custom element. It would require list on <input>, and if that had to be data-list, there would be nothing indicating its relationship to the custom element (unless the custom element was also called <data-list>, which would actually be very suitable in this particular case, but this doesn't generalize, whereas the problem does).

The suggestion about requiring a hyphen seems the most reasonable to me: it addresses most of the problem, it's consistent with custom elements, and is consistent with existing practice.