I don't understand BEM very well, and I acknowledge this, and I am trying to be better.
At Bolster, we’ve incorporated BEM as part of our frontend methodology, and I’ll admit that I’ve probably had the most trouble adapting to it.
I’ve read all the articles and seen all of the diagrams of how to name things according to “bemmy” principles. The problem I found I had, however, was that by giving every element on a page a unique name, I was left uncertain of how to share styles between similar page components.
Getting specificity vs. reusability through my thick skull:
Let’s say I have a
feed-item on one page, and on another page I have a slightly different variation of a
feed-item (let’s call it
feed-item--compact). As I understood BEM,
feed-item--compact wasn’t supposed to share styles with
feed-item. This way,
feed-item-compact could be moved around and reused independently of any other code.
I realized that the answer to my problem rested with how I interpreted BEM’s guidelines. While my variations on
feed-item should most definitely carry modifiers (like
--compact), there’s no reason tht I couldn’t also have the
feed-item class on the component’s HTML, and simply use
feed-item--compact as a place to put the styles that differentiate it from the default one.
Honestly, I’m not sure why it took me this long to realize it, but it’s something that I don’t recall seeing explicitly mentioned in many articles on BEM. You can have as many classes on an element as you need, and I would say that ideally you should have a class for each level of specificity you may require:
<div class="feed-item feed-item--compact">...</div>
…which, if you ask me, is every level of specificity… because you never know when you’re going to need it. It’s easier to simply not write some CSS for a class than to have to add that class to your markup later down the road, when you realize you needed the specificity (durr, again, that’s BEM for ya).
Of course, if
feed-item--compact really is supposed to look completely different than
feed-item, then by all means re-specify those styles.
How I’m probably abusing modifiers:
I’m also not sure if this is mentioned anywhere, but I have a tendency to use
--modifiers on both
elements. So I may write something like:
<div class="user user--premium feed-item--compact__user--premium">
I’m probably wrong about it, but hey, it works for me and I’m trying not to step on any BEM toes in the process.
In which my OCD about things hinders progress:
Okay, here’s one thing that really bugs me about BEM: the misuse of
-. Multi-word tokens in a BEM classname are separated using hyphens, which breaks double-click selection behavior in most editors. Trying to double-click the
feed-item--compact is a pain.
Here’s something more like what I’d rather do (though I’ve had trouble convincing anyone else to do this along with me):
<div class="user user__premium feed_item__compact--user__premium">
This way, each component (complete with its modifier) is quickly selectable by double-clicking. The underscore is used to represent spaces between words (as intended) and a hyphen is used to represent the combination of two independent components (again, as they are intended to behave).
If you really wanna get fancy… let’s use the em dash
— rather than
__ and keep our block-from-element separator down to a single, tidy hyphen:
<div class="user user—premium feed_item—compact-user—premium">
Isn’t that nice? Though—to be fair—for that to work most coding fonts would need to better distinguish the em-dash from en-dash or hyphen, given their fixed-width nature. I’d be open to suggestions.
In the past with our CSS, we usually used the hyphen to separate our crude, un-bemmy element names from our unenlightened block names… like
menu-item. Now, we’re using the hyphen within the element name, or within the block name. To me this seems like a common mistake in syntax styling that needs correcting.
But that’s just me. ;-)