Open tadatuta opened 9 years ago
Easy maintenance is what BEM was invented for.
Actually all the issues with CSS maintenance are because of cascade and strong coupling of
Is it clear? I think focus on CSS is quietly wrong. BEM is about blocks at first, and then about CSS, as a part of some block. It looks for me as a limit while methodology itself shouldn't has limits.
@zxqfox Please refer https://en.bem.info/forum/issues/6/ for answer ;)
@tadatuta :+1: :smirk_cat:
Hi, some time ago jQuery team asked us about BEM, and we cleared a lot of points for them. Answers are quite useful, so we decided to publish them free.
1. How easily is BEM kept maintainable long term?
Easy maintenance is what BEM was invented for.
Actually all the issues with CSS maintenance are because of cascade and strong coupling of components. And BEM is all about independence of blocks and reducing cascade to minimum level.
We have a lot of real experience with BEM on our portal and it proved to be a great solution.
Example 1.
won't work as soon as you'll get second level of nesting for lists.
Example 2.
Considering menu can't have any other list items:
and then some components with own dropdown with own menu appear in list item.
2. The long class names can come off a bit intimidating and unfriendly for beginners using BEM. What is the justification behind the longer names? As it is now, we already have many people complaining when we use
ui-button
for a class name instead ofbtn
, because the former is too long.Well, BEM does not restrict usage of
btn
instead ofbutton
;) You can consider any naming strategy you want. E.g.:context
orctx
orc
,attributes
orattrs
oras
.The choose is yours — BEM doesn't srink you.
There is still some "problem" with elements and modifiers, i.e.
btn__txt
andbtn_hvrd
, but we strongly believe that there's no real problem in typing. And of course there's no problem with kilobytes due to gzip. But what is really important for huge rapid projects which live for a long time is code readability and self-descriptive names of components is just a must.Not so cool for common block library with a huge amount of users.
3. The namespacing decisions in general - members of our community would like a greater explanation of this.
That was something odd when we invented BEM. But right now that's a common idea: OOCSS, Atomic CSS, etc. and web components standard try to hide internal world of a block from other ones. Web components use shadow DOM, BEM uses namespacing to achieve the same result but without necessity to wait for support from browsers or any additional JS.
Historical reason of having namespaces for modifiers is that joined selectors like .a.b were not supported in old browsers. Not it's not a restriction but in BEM there's also a concept of mixes — possibility to have a few different entities on the same DOM node. And namespaces help to distinguish modifier of which block is it.
Without mixes it's possible to have
.btn._hvrd
but we are sure that mixes are useful thing.But what is often left in shadow is possibility to mix different entities on the same DOM node. E.g. it's possible to have
<input class="input form__login">
which means we've got aninput
block (can be reused somewhere else) andlogin
element ofform
block at the same time. So everything about abstractinput
will be provided by.input
selector and things like margins, etc — with.form__login
.4. Neutering the Cascading potential of CSS code by making everything overly specific.
Yes, that looks strange at the first sight but soon you'll find it very convenient. Cascade is cool for fast write-and-throw-away approach. But when we need bullet proof reusable components it just doesn't work.
Cascade creates strong coupling and results in impossibility to reuse such code.
5. The arbitrary distinction between blocks and elements.
Let's look at JS (actually OOP) analogy. JS class point [x, y] is just a field of Figure class or one more class Point. If it has a lot of methods it's most likely a class by its own. Otherwise field is enough. The same is for blocks and elements. It's always for your consideration.
With practice that's easier than it looks. When an entity is impossible without its parent — that's an element. When you find yourself trying to reuse an element somewhere in a project without its parent and inner complexity of element became bigger — that's a standalone block.
But what is often left in shadow is possibility to mix different entities on the same DOM node. E.g. it's possible to have
<input class="input form__login">
which means we've got aninput
block (can be reused somewhere else) andlogin
element ofform
block at the same time. So everything about abstractinput
will be provided by .input selector and things like margins, etc — with.form__login
.