amcss / attribute-module-specification

The Attribute-Module CSS (AMCSS) Specification
MIT License
393 stars 8 forks source link

Custom Attributes rather than am- prefix? #4

Closed fvsch closed 10 years ago

fvsch commented 10 years ago

This is part of the feedback I emailed Glen earlier this week.

Custom Attributes?

This may be bikeshedding but I was not a fan of the am- prefix, partly because it reads like the “am” in “I am” or like “A.M.”, and partly because the name “Attribute Modules” doesn’t sound right to me and I would have expected “Module Attributes”, grammatically speaking. I guess “Attribute Modules” work as the name for a methodology, but as the name for a specific HTML idiom, I’m not sure.

So this got me thinking, why not shoot for the stars and try to get Custom Attributes?

The basic idea for Custom Attributes is to allow as standard — and to begin with, as a well-known coding practice — the use of arbitrary HTML attribute names that follow this pattern:

Basically anything matching:

/[a-z]+-[a-z\d-]+/

Or reusing the language from Custom Elements:

The custom [[attribute name]] is a sequence of characters that must match the NCName production, must contain a U+002D HYPHEN-MINUS character, and must not contain any uppercase ASCII letters.

(Okay I’m not well versed in the formal language that the XML spec uses so I’m not exactly sure what NCName allows. Maybe it’s too permissive.)

The convention for “native” HTML attributes is to use /[a-z]+/i, with no hyphen. This is confirmed, as far as I know, by all “HTML5” attribute names, such as contenteditable, contextmenu or srcset (two-word names don’t use an hyphen or any separator).

There are a few exceptions in existing HTML attributes, mostly HTML 1–3 legacy stuff. These could be listed as explicit exceptions. The Custom Elements spec does it for element names from the handful of SVG and MathML elements which contain an hyphen. So we could say:

The custom attribute name must not be one of the following values:

  • any value starting with data-
  • accept-charset
  • http-equiv

(Thankfully it’s a short list. I used MDN as a reference, limiting the scope to HTML.)

Recently for ReMarkdown I’ve used a data-rmd="some-option another-option" attribute. With a “custom attributes” community standard, I could pick a different attribute name such as:

The obvious option, remarkdown="…", would still be considered “illegal”; a bad practice because of a risk (albeit really small in this specific case) of colliding with a future standard attribute.

Custom attributes become more obviously useful when you have several attributes for your module which all use a prefix. Currently I’m building a library whose prefix is pcards, so I could use pcards-color, pcards-size, pcards-type instead of the data-color, data-size etc. that I’m currently using (and which pose more of a risk of collision with other libs). Or just pc-color, pc-size, pc-type if I want something shorter.

Likely objections

Just noting some likely objections to both your proposal and my limited suggestion.

  1. “We already have data-*”. True. People could just use data-mymodule and data-mymodule-someparam. Custom attributes would allow to separate data-* stuff that is data relevant to the content from module-scoped styling and behavior hooks. Also mymodule-x and mymodule-someparam are shorter than their data-mymodule-* equivalents. :)
  2. “Custom Elements / Shadow DOM fixes that.” True, but only in cases where it makes sense to define a module as something contained in one element (a Web Component). It works for specific parts of web applications, but not for general and atomic UI styling that doesn’t suck.
benschwarz commented 10 years ago

Thanks @fvsch, its really good to see this collated here.

I think our specification should suggest usage of am-Component-name or data-Component-name, or for people to come up with their own prefix (eg sg-Component-name, short for style-guide). In short, the prefix really isn't important. Its important as a distinction that a given component comes from a given source.

On data-

Angular popularised using ng- as an attribute prefix, while also suggesting / allowing people to use data-, which, I think was a bit of a cop-out. (I believe) that it was done to appease dorks and complainers that would (so rightfully) quickly point out that custom attributes aren't 'valid'.

Onward

At the end of the day, it really doesn't matter, but I can see a point to not popularising a poor practice of inventing your own attributes (or elements!), because it sets a precedence for the community at large.

To that point, I believe amcss to be a project about experimentation and discovery… and while so many are currently "componentsing" their front-end codebases, I think that this kind of experimentation should be welcomed (thoughtfully, and carefully).

fvsch commented 10 years ago

Perhaps it would be an option to have language that says something like:

amcss attribute names must start with a Prefix, followed by an hyphen, followed by a Main part. Prefixes are lowercase alphabetic caracters ([a-z]). The Main part of the attribute may contain any character valid in an HTML attribute name, including hyphens.

Consequently, all amcss attribute names must contain at least one hyphen. The following names must not be used as amcss attribute names: accept-charset, http-equiv.

Additionally, in the amcss methodology, both Prefixes and Main parts of amcss attributes are expected to follow a set of conventions, which are described in the next 2 sections.

Attribute prefixes

amcss recommends two naming paterns for prefixes, and acknowledges a third one.

  1. Using the am- prefix.
  2. Using any prefix of your choice. This prefix must not be a Component name.
  3. Using the data- prefix. This option is not recommended, because while it offers HTML5 validity, it doesn’t allow for separation between amcss attributes and general-purpose metadata. We consider data-* attributes to be more suited for additional content or information added to elements for scripting use; not style and behavior hooks.

Attribute naming convention

[… stuff about Component etc. here …]

Food for thought. :) (I’m not writing anything about the Component-etc. parts here, because I’m not sure what’s your plan for that.)

benschwarz commented 10 years ago

:+1: Great stuff @fvsch

thefoxis commented 10 years ago

I agree data while more familiar could cause confusion and possibly mismatching with JavaScript. By the way @benschwarz you might find this discussion on accessibility of role attributes quite interesting.

geelen commented 10 years ago

I think we can close this issue for now. Pretty happy with where we landed on it.