Search code examples
javascripthtmlattributescustom-element

Is it good practice to create custom HTML attributes for custom elements?


When creating a custom element like <input-field>, should custom attributes still use the 'data-' prefix or would it be acceptable to simply use them as-is? Basically using variation="abc" vs data-variation="abc" for example.
And if it is allowed, would re-using existing attributes like type be allowed?

In addition, would it be bad practice to add custom properties to the element's object during creation like the following:

class InputFieldElement extends HTMLElement {
    constructor() {
        super();

        this.customProperty = {data: 123};
    }
}
customElements.define('input-field', InputFieldElement);

I'm aware that these methods work perfectly fine right now, but the question is more if it's actually intended behavior or if it's just a weird edge-case that could stop working at any moment.


Solution

  • I have asked a similar question more than 3 years ago.

    You're free to choose almost any attribute name you like, except the universal attributes ( e.g. id, class, title). In some cases even re-using attribute names that exist on some elements (like e.g. value, disabled, etc.) makes total sense so component consumers can work with your elements as though they were existing HTML elements.

    Remember this freedom only applies when using autonomous custom elements (<foo-bar>), not when extending built-ins (<div is="foo-bar">)!

    As to your second question, it's also totally okay to define/add properties in the constructor, but recent additions to the ES standard have added public and private class fields:

    class InputFieldElement extends HTMLElement {
        customProp = {data: 123}; // public class field
        #abc = "Hello"; // only accessible from within this class via this.#abc
    }
    

    Except the private member, this class does exactly the same your class did, effectively saving you the need for a constructor. Please note that this is not yet available when assigning values to private or public class fields, meaning you cannot setup computed properties this way.

    Regarding your specific question asking for type, having that attribute usually is an indicator of bad class design (which is true for HTMLInputElement e.g., resulting in text inputs with a use- and meaningless checked property, and checkboxes that have a readOnly property (which won't do anything either)), but cannot be changed any more due to web compat.