Can a custom element use arbitrary attribute names safely? - html

There are very clear rules for how custom elements should be named. The main difference to other HTML elements is that they must have a non-leading hyphen. While it's possible to load an HTML document that includes made-up tag names that don't stick to these rules, it's supposed to guarantee a certain level of future-proofing and platform support.
However, I'm looking for guidance on how to name attributes for my custom elements. For readability and convenience I would prefer to use short, descriptive attribute names, e.g. not using a data- prefix for everything, but I also want to be sure things won't break as new features are added to HTML5. My research so far has not given any clear answers, and suggests that in practice, it's a bit of a wild west.
For example, the W3 HTML5 validator seems to accept made-up attribute names that follow basic conventions like using only a-z and hyphens, but only when they're used on custom elements. It complains about things like using special characters or repeating the same attribute, so that suggests that it's not simply giving up validation completely on a custom element, but actually considers arbitrary attribute names to be valid in that context.
Google's developer resources as a page Custom Element Best Practices, but as far as I can tell it does not answer this question. However, their examples seem to stick to using existing attribute names like checked and disabled. Examples from Google's web component-focused javascript library Lit seem to make use of arbitrary attribute names, however.
My question boils down to:
What, if any, is the official word in the spec on how to name custom attributes for custom elements?
If there's no official word, what is considered to be best practices? How can anyone using custom elements be sure that their attributes will not trigger unexpected functionality in future browsers?

The specification defines the attributes accepted on a custom element as:
Global attributes, except the is attribute
form, for form-associated custom elements — Associates the element with a form element
disabled, for form-associated custom elements — Whether the form control is disabled
readonly, for form-associated custom elements — Affects willValidate, plus any behavior added by the custom element author
name, for form-associated custom elements — Name of the element to use for form submission and in the form.elements API
Any other attribute that has no namespace (see prose).
And then says
Any namespace-less attribute that is relevant to the element's
functioning, as determined by the element's author, may be specified
on an autonomous custom element, so long as the attribute name is
XML-compatible and contains no ASCII upper alphas. The exception is
the is attribute, which must not be specified on an autonomous custom
element (and which will have no effect if it is).
Customized built-in elements follow the normal requirements for
attributes, based on the elements they extend. To add custom
attribute-based behavior, use data-* attributes.

Related

Question about a code in a Django Girl's tutorial [duplicate]

I've recently found on one of the sites opening tag like this:
<script data-ip="93.1xx.3.2x" data-backuri="something.com">
And I couldn't find any information about it. What are those tags used for?
data-* attributes are custom HTML attributes.
Basically, there are standard HTML attributes like style, src, width, height, class... and these have a special meaning to browsers and are 'reserved'.
However, custom attributes have no special meaning generally and are only special to the owner's application. They can be used to simplify an application's logic.
Using data- before your attribute name ensures that future standard attributes will not use your current attribute. For example, imagine today you are using a sound attribute but then the HTML standard adds a sound attribute meaning something other than what you meant. Had you used data-sound, you would have been fine because there would be no conflict. The specification says no future standard browser attributes will start with data-.
See jquery get HTML 5 Data Attributes with hyphens and Case Sensitivity for some useful info on why we use data-* attributes.
Also, see MDN docs for some useful information.

Are there technical reasons not to use undefined custom elements for everything?

Some people seem to like to rewrite
<div id="homepage">[...]</div>
as
<app-homepage>[...]</app-homepage>
Are there any technical or spec related reasons not to do this? Mind that I am talking purely about changing this on the level of the HTML and CSS; The elements have not been defined using the custom elements API.
Tl;dr: Don't do it. Use the custom element spec for what it's made for. Hacking together your HTML syntax is not what it's made for.
Semantics
First of all custom elements in general can break up the semantics of the DOM structure. When custom elements are used properly you receive a lot of power in return, but in this way you give up semantics without any benefit. Instead use the proper HTML5 elements like <header>, <article>, etc.
Undefined custom element state
According to the custom elements spec such elements have a custom element state of
"undefined" (not defined, not custom)
Now, the way the HTML spec works any element which isn't recognized has a defined behavior of create just a default undefined HTML element instance.
Up till the custom element spec it was incredibly dangerous to define such elements because there was a risk that a future version of HTML would implement it, but now all elements with a - are reserved for custom elements.
Does that mean that you are entirely safe? No, because you put yourself in the same namespace as all other custom elements. And unlike with external stylesheets there is no proper way to namespace them, so if you wish to do something like this you will have to write code like
<my-app-name-homepage>[...]</my-app-name-homepage>
and even then you still end up with an element with an undefined state.

What does the "dynamic" attribute mean on a "span" element?

I have come across the following tag, and am really curious as to what the dynamic attribute means. Google is not being very helpful, as it returns most results for dynamic attributes and dynamically adding attributes, not for this attribute itself.
So, what effect does the dynamic attribute have on span, and possibly other, elements?
There is no "dynamic" attribute according to the standard. However, it has always been possible to add arbitrary attributes to elements for various reasons and I guess this is one of those cases. HTML5 defines a standard way to add "dynamic" and/or "custom made" attributes to elements, that's by prefixing the attribute with "data-". If you do that, you can have your own "data" attributes but still validate your document according to the HTML5 standard.

Custom attribute with data-* prefix or without?

The HTML5 spec define how to set custom attributes using data-* prefix,
like:
<div data-attr="somedata"></div>
But what would be the difference if we write just:
<div attr="somedata"></div>
And I actually prefer the second way since it's shorter.
I can access both attributes using the getAttribute() method.
So is that wrong not using data-* prefix? I tested it only on chrome and IE11, so maybe there are other browsers to worry about?
HTML5 defines the data-* attributes as valid, while other custom attributes are not. So what?
If you run your code through an HTML validator it will look for invalid attributes. Among other things, they could indicate a typo. An HTML5 validator will accept data-* attributes but it isn’t psychic. It has no way of judging which other new attributes are part of the plan.
If you create a new attribute, it may not play nicely with future changes in HTML which may coincidentally use the same attribute name for a different purpose. The data-* attributes are exempt from future implementation.
A corollary of the above is that including additional libraries which also make arbitrary changes may interfere with your own code.
JavaScript cooperates with the data-* attributes by automatically collecting them in a dataset property for each element. If you make up another attribute it won’t be included.
If none of the above points are important to you, then, by all means, use whatever attribute names you like. As regards the last point above, you can always access your own arbitrary attributes using JavaScript’s *Attribute functions which will work just well on any attribute, regardless of its validity.
Speaking of JavaScript, there is no concept of HTML validity for JavaScript, and you can use JavaScript to assign any attribute names you like without fear of the HTML validator police knocking at your door. However, you still run the risk of competing with additional libraries or future implementations.

Consequences of Custom HTML Tags in AngularJS Directives

Say I wrote a custom gravatar directive in AngularJS that is bound to an email property on the scope. The directive would replace this HTML …
<gravatar email="user.email" />
by a common img tag whose src attribute is set to the correct Gravatar url:
<img src="http://gravatar.com/avatar/..." />
My question might be a little broad or even naïve, but "how bad" is it to initially have the <gravatar /> tag in my page's HTML? Are there any "real-world" consequences besides not passing W3C validation?
The W3C says
Authors must not use elements, attributes, or attribute values for purposes other than their appropriate intended semantic purpose, as doing so prevents software from correctly processing the page.
and
Authors must not use elements, attributes, or attribute values that are not permitted by this specification or other applicable specifications, as doing so makes it significantly harder for the language to be extended in the future.
http://www.w3.org/html/wg/drafts/html/master/dom.html#elements
Custom elements/attributes have no semantic value and should be avoided for these reasons.
There probably won't be any direct consequences that you will even notice. After all, Angular itself uses the non-confirming ng attributes (although they do support with the data- prefix as well).
The only possible problem you may face is if the element you introduce that is currently a custom element becomes part of the spec and has different behavior than what you were expecting before, but I think that is highly unlikely. Even so, I would avoid using anything custom if I could.
Eventually you will be able to register your own custom elements, but from what I can tell no browser supports this spec yet.
While the initial source of the page body (before angular processes an ng-app element) may not adhere to the W3C standards, if you use "replace: true" in directives, custom elements are replaced by a template HTML, which can be valid. So, in this case, you can think about an angular element as just a placeholder that is replaced with the terminal HTML output.