[Custom Elements] Not requiring hyphens in names

This is the issue that is being avoided by having this limitation. It’s a hard demarcation between official and user naming conventions such that naming collisions between the two can’t occur (and also hopefully reducing collisions in user space by encouraging the prefix to be used as namespacing).

If anyone tries to suggest a new element and there’s a hyphen in it that will be the first thing that will be picked on as needing to change.

This is the opposite of short-sighted, it’s actively preventing future issues.

I suspect there were discussions on that and I suspect that the answer would have come back to “well we need these and unfortunately anyone not using best practices because they are polluting global scope may be affected”. Just because standards have broken sites doesn’t mean there’s no concern about it, nor does it mean steps shouldn’t be taken in future to minimise it.

This basically means every component will need a long list of every native element they depend on and everyone using a component is going to need to start cross referencing for what should be built in functionality. All that allowing this change would do is massively increase the complexity of checking dependencies all for the sake that some developers find it a little bit more aesthetically pleasing.

I’m saying that it seems short-sighted to always assume a single word for builtin element names in the future because it doesn’t seem like it’s making the web easier, accessible and intuitive for developers (which I always thought the web was, but I’m fine with being wrong here).

So we’re basically saying that if, in the future, we want to add a RadioButtonGroup builtin element, it will be named <radiobuttongroup> instead of <radio-button-group>? That just seems really hard for me to wrap my head around (i.e no delimiting, inconsistent word matching in IDEs). But I’m pretty hard-headed, so I guess the shoe fits. :slight_smile:

@mkay581 From the spec:

“They contain a hyphen, used for namespacing and to ensure forward compatibility (since no elements will be added to HTML, SVG, or MathML with hyphen-containing local names in the future).”

We can do a whole lot without any separators <radiogroup> for example seems entirely reasonable and in keeping with everything in HTML so far.

If we absolutely can’t, HTML and SVG can simply use any other separators that work with the parsing model besides dash

If you mean “here” as in this thread, no… that’s not the topic of this thread, just related. If you mean here as in on wicg, I have suggested that several times to folks interested in it, a number of them aren’t ‘here’ I think though there may be a thread already. @matthewp may know.

By “we”, who do you mean? And can you give examples of how you can do so much without any separators? I personally only see things like pattern matching hell when there is both a radio element and a radiogroup element and there is no delimiting factor to tell the difference between the two. But I guess this may be a small price to pay and may really only be a concern for lower-level engineering initiatives that probably won’t apply to the masses in the developer community.

s/we can/it is entirely possible to

if that helps?

<radiogroup> seems entirely reasonable in HTML to me. Some will complain it’s too many keystrokes already to be honest. Initial tags that HTML was even based on took words like “unordered list” “list item” and made them things like <ul> and <li>. If some new HTML tag really needed delineators, there are others besides dash.

This basically means every component will need a long list of every native element they depend on and everyone using a component is going to need to start cross referencing for what should be built in functionality.

You yourself said we shouldn’t pollute globals. Well, having a global CustomElementRegistry at window.customElements is an example of global pollution in two ways:

  • We just added a global to window
  • This new global gives users further ability to define global elements.

This is opposite of your desire to not pollute globals.

A while back I proposed component-scoped Custom Elements, but that issue was closed because (I’m guessing) the powers that be prefer global pollution.

Every (every) web framework these days (React, Vue, Angular, etc) has a way to scope elements/components to the internals of the components they are used in. It seems like an obvious thing the web should learn from…

Yeah, I mean on WICG.

Creating a ponyfilled [1] element isn’t about aesthetics. Its about providing functionality to users with declarative facilities while conveying the semantics of what the element does. The latter is especially true of customized built-in elements, where an existing element can be safely inhabited by a JavaScript implementation without polluting the global scope.

I like the idea of allowing a new non-hyphenated name, tagged with is=“pony-fill-name” attribute, to behave like a standard autonomous custom element, as suggested in this thread (or possibly elsewhere) by @trusktr.

In my opinion, the need for customized built-in elements is closely related this: to help shape the standards process. I don’t see the need for inheriting behaviour (beyond parsing, I’m guessing), which I think is why Safari objected to the is attribute (mostly?). Why couldn’t customized built-ins extend HTMLElement at most? @briankardell Then when ‘mixin’ facilities are available in some future standard, they could use those to build up to more potent functionality.

Such a facility could be used by community projects, for example the Responsive Images Community Group’s picturefill, to provide working prototypes that closely resemble the target syntax, but don’t pollute the global scope or squat on names. If there was the ability to create non-hyphenated named custom elements like <picture is=“picture-fill”>, there might never be another need for a ‘speculative polyfill’, which are described by the TAG as risky [1]:

“Early, speculative polyfills help shape the standards process. However, any JavaScript library that defines a property of the global object or extends a prototype of a global constructor using a proposed or generically useful name, risks creating problems for the development of the Web if that library becomes widely used, prior to the standardization and implementation of the feature it seeks to create or emulate.”

It would be better, I think, to use ‘early speculative ponyfills’ in helping to shape the standards process, because they don’t carry the same risk, and in fact wide use is a better indication of the viability of a standard.

[1] https://github.com/sindresorhus/ponyfill [2] https://www.w3.org/2001/tag/doc/polyfills/#risks-of-premature-polyfilling

I don’t know why I was tagged on this one, but my opinion is that hyphens are fine. :slight_smile:


Yes. People could use the part of the element name before the first hyphen like an XML namespace prefix without the globally unique name that actually makes it work. It still doesn’t prevent another library from changing your elements though.

I had a proposal at one point for a reasonably efficient implicit binding mechanism (“unobtrusive namespaces”) to say that, in such-and- such a context in my documents, element foo belongs to bar. It didn’t fly in the distributed extensibility discussions, partly because I did a poor job of promoting it I think, and partly 'cos I didn’t use JSON :slight_smile: although i did have an implementation outside the browser.

It might be that “ownership” combined with some sort of sandboxing would help with this, as well as considerably helping with security of server-side included content (e.g. advertising).

As customn elements take off it’ll be an increasing problem, though.

What do you all think of shadow-root-scoped Custom Elements?

I also implemented “Element Behaviors” in my project here, but I haven’t published it separately yet.

Basically, you define a class with lifecycle methods similar to Custom Elements, with the difference that each behavior receives the target element into each callback, and this refers to the behavior instance, not the element, and thus avoids any requirement for inheritance:

class AwesomeBehavior {
  constructor(element) { ... }
  connectedCallback(element) { ... }
  disconnectedCallback(element) { ... }
  attributeChangedCallback(element, attr, oldVal, newVal) { ... }

So you see, this is separate from element, so you can keep stuff encapsulated inside a behavior, or you can modify the element directly (with caution).

Then, you define the behavior:

window.elementBehaviors.define('awesome', AwesomeBehavior)

The name of the behavior doesn’t need to have a hyphen!!

Then, you add the behavior to any element using the has="" attribute:

<div has="awesome"></div>
<any-element has="awesome"></any-element>

And you can add as many behaviors as you want to an element (unlike the stubborn and complicated is=""):

<button has="awesome other-behavior another-one"></button>

And now that button element will have three behaviors instantiated for it, each with their lifecycle callbacks for reacting to the element’s lifecycle.

Lastly, the behaviors can be accessed directly on an element like so:

element.behaviors.get('awesome') // it's a subclass of Map
for (const [name, behavior] of element.behaviors) { ... }

This doesn’t have to do with Custom Elements specifically, but just sharing it as an alternative to many cases where one might use a Custom Element but… this doesn’t require a hyphen in the naming! :blush:

The reason I mentioned my shadow-root-scoped Custom Elements idea is because in that case component authors would have fine grained control of what element names mean in their components. When new builtins are released, they will be shadowed by the component’s element definitions if there is a name conflict, so it will not break the component. The author could later decide to rename a CE to something else and to then use the new element.

This concept I describe is exactly how global variables work in JavaScript: a variable in a sub scope shadows the variable from an outer scope when the names match (it isn’t really a conflict then).

There’s no reason why we shouldn’t aim to do this in HTML.

Choosing for Custom Elements to be globals is a huge mistake.

I realized I was a little harsh in my language above. Generally speaking, I think we (w3c and anyone involved with community discussion) can do better than to introduce new global-style APIs because we’ve already proven in large applications that relying on globals is definitely not ideal.

Any discussions you can point to? Since we’re talking about it.

Here’s a working example of my “element behaviors” idea (note the use of the has="" attribute to associate any number of behaviors which are effectively similar to “mixins” but not quite mixins in the JavaScript sense):

I can try to look later for specific references but in case I forget or you’re just more motivated than me: IIRC in Web Platform WG for over a year I believe that apple, google, mozilla and ms have all expressed interest in pursuing this, many explicitly over is="…", I’m sure that you can find references if you search the archives, particularly TPAC meeting minutes. I know that there are some github issues to begin to break down the ‘special’ magic that already exists in the platform so they could even be mixed in (like how can you mix in form participation or something). Maybe someone else (@slightlyoff ?) has a link handy?