yandex / reshadow

Markup and styles that feel right
https://reshadow.dev
Other
363 stars 15 forks source link

Additional alternative syntax for modifiers #36

Open kizu opened 5 years ago

kizu commented 5 years ago

In short: currently the only documented way to have BEM-style modifiers which are not based on rendered attributes is use:foo in HTML and [use|foo] in CSS.

There is an undocumented way to do the same with just _prop in HTML and [_foo] in CSS.

I think that should be an officially supported feature, available as a shortcut/alternative way to use the non-rendered props for conditional/targeted styling.

Pros:

  1. Shorter syntax. Just one symbol instead of four in both HTML and CSS.
  2. More consistent syntax: it is just the same prop in both HTML and CSS. The existent namespaces syntax makes it easy to make typos by writing something like [use:foo] in CSS.
  3. Easier to find using search: by looking for _foo you would find the modifier both inside CSS and HTML, while when you'd have use:foo and [use|foo], looking for just foo would return more messy result, and you'd need to use regex/multiple searches to find the modifier everywhere.
  4. Props/attributes that start from underscore are supported everywhere, so they can be used for plain HTML & CSS when testing component code in, for example, CodePen.
  5. This syntax could be used in places where the use: namespace is already taken, for example, in Svelte.
  6. This syntax would be familiar to those who know BEM.
  7. This syntax could be also used not only for “modifiers“, but for “elements”: instead of <content as="p"> in HTML and content {} in CSS you could write <p __content> in HTML and [__content] in CSS, making it harder to use default <div>s and promoting the usage of semantic elements. This, of course, would be also entirely optional and just as one of the potential ways to use reshadow.

Cons:

  1. A need to support/document two syntaxes. This is slightly mitigated by underscore syntax being very easy to implement (basically, just omit any props starting from _ from rendering in HTML).
  2. Potential inconsistency in the code. It should be possible to create a linter option to allow/disallow certain ways of doing such modifiers, this would allow developers to remove any potential inconsistencies.
  3. There is a possibility that some other project could have its own meaning for props starting with underscore, but in plain HTML such attributes are not valid (so it would be ok to discard them from the built HTML), and if it would be used just for styling in reshadow, there shouldn't be any substantial problems caused by this. I also didn't encounter such props in other projects, and have used them by myself as a way to name visual-only props.

Overall, I find the pros to overwhelm the cons, and I think we could have both ways of doing modifiers at the same time. The underscore props are implemented easily (and work already) and having multiple ways of doing things can make it easier for people to adopt reshadow, as they could choose the way that is closer to them.

lttb commented 5 years ago

thank you very much for the proposal, I really like your points and I'm in 🙂

so it's time to unskip these tests and UNBLOCK THE BEM POWER 😄😄😄

the thing that I'd like to consider before the publishing this feature are elements:

<__element as="p" />

You were talking about attributes, but theoretically, this kind of elements declaration might be useful too, and it solves the elements ambiguity problem that reshadow has:

<__title as="h2" />

vs

<title as="h2" />
kizu commented 5 years ago

Hmm, I feel like it should be safe to allow underscores in the names, I'm not sure if I would use it, but I see how this can be useful for someone.

However, testing it with react: it actually supports components from variables named with a leading underscore, couldn't this be a potential problem?