Description
Recently, my team (within Chrome) has been working on initial explainers and explorations for new HTML elements: a virtual scroller, a toggle switch and a toast. There are a couple common issues we're attempting to tackle with these that need a central place to discuss, and the whatwg/html community is a good place to have those. These issues are polyfillability, and pay-for-what-you-use. They are somewhat connected, but I want to try to use two separate issues to discuss them; we'll see if that works. This issue is about polyfillability.
The problem: if we introduce new HTML elements the same way as we have in the past, they are not polyfillable, because custom elements are restricted to have a dash in their name, whereas built-in elements traditionally do not.
In the past this hasn't been too much of an issue; we'd introduce new HTML elements that aren't polyfillable anyway, such as <dialog>
(magic top layer/inertness), or <details>
(magic slot=""
-less shadow DOM and marker rendering). Some new element proposals follow this trend: e.g. <portal>
introduces a fundamentally new way of dealing with browsing contexts, that needs deep integration into the internals of browsers. But the ones I mention above do not; they explicitly attempt to follow the extensible web manifesto and not build any new magic into the element. I.e., if it weren't for the dash issue, they would be polyfillable.
There are several potential solutions we've thought of so far. I'll outline them here, but I'm sure the community can think of others. Note that the specific names ("virtual scroller", "switch", "toast") are used as examples, and discussions on those repos may point us toward better names (e.g. WICG/virtual-scroller#163).
-
Introduce a new dash-containing prefix for such polyfillable built-in elements, e.g.
<std-
. Use it everywhere. Result:<std-virtualscroller>
,<std-switch>
,<std-toast>
, ... -
Ensure that such elements have at least two words in its name, and separate them by dashes, instead of HTML's usual
<textarea>
or<frameset>
convention. Result:<virtual-scroller>
,<toggle-switch>
,<toast-banner>
, ... -
Minimize visual noise by just using a dash suffix. Result:
<virtualscroller->
,<switch->
,<toast->
, ... -
Lift the restriction that custom element names require a dash, thus allowing them to be used to polyfill built-ins. Result:
<virtualscroller>
,<switch>
,<toast>
. This is where things get interesting; let's dig in to the details.- Why did we divide up the namespace in the first place? To avoid future conflicts with new browser-provided elements. I.e., what happens if code does
customElements.define('awesomeelement')
, but browsers later introduce a native<awesomeelement>
? It would either break web pages, if we madecustomElements.define()
throw, or it would require extra work from browsers, to allow native<awesomeelement>
s to get converted into custom<awesomeelement>
s (probably using a variant of the custom element upgrade machinery). Note that one route out here is to implement that conversion. - But this issue is predicated on browsers introducing new elements to the global namespace. What if they didn't, or did so only rarely? For example, if we declared that all new elements will not be added to the global namespace, but instead only appear to pages that load a corresponding built-in module, then there would be no future collisions to worry about.
- Even in today's world, the custom element dash restriction is not a guarantee of conflict avoidance. Authors are already using non-dashed element names, e.g. https://www.apple.com/shop/product/MRXJ2/airpods-with-wireless-charging-case uses
<favorite>
,<overlay>
,<loader>
,<content>
, and<validator>
. Or the famous picturefill incident. In practice, introducing a new element already requires some compat analysis on the existing web. So one possibility is that we could say that most new elements (maybe, all polyfillable new built-in elements?) use a built-in module or other opt-in form, but if we really need something baked in to the global namespace, we can do some compat analysis and figure out a name that works. - We could continue to encourage a cultural norm that dashes be used for most custom elements, reserving non-dashed custom elements mostly for polyfills. It's unclear whether this would work, but we have weak evidence, from the fact that relatively few sites are using undashed non-custom elements such as
<favorite>
or<loader>
, that the norm might continue to hold.
- Why did we divide up the namespace in the first place? To avoid future conflicts with new browser-provided elements. I.e., what happens if code does
Looking forward to hearing folks thoughts!