Overthinking BEM
In “Learning to love BEM” I professed my newfound love for the BEM syntax. I’m happy to report that after more than 2 years, I’m still happy with my choice.
When we have the choice of code style in our projects, we use a combination of BEM and ITCSS. A few days ago I came across Spatie’s Guidelines website. In the section on CSS I found a few parts that got me thinking.
What to do with “grandchildren”?
The first one is the concept of the “grandchild”, which is not a part of “standard BEM” (if there is such a thing).:
.component /* Component */
.component__element /* Child */
.component__element__element /* Grandchild */
I understand where this idea comes from. One of the basic premises of BEM is that a component consists of blocks and elements. The child of an element is denoted with two underscores (example: .gallery
and .gallery__item
).
What if the child has a child as well in the underlying HTML? Logic would say that you would use this grandchildren approach. My experience tells me this leads to unnecessarily long class names (which BEM is already faulty of); and that it’s unnecessary to try to reflect the structure of your HTML in your CSS.
It took me a while to get over that last one. It seems like such a clean idea to reflect the underlying structure of your HTML in your CSS. Once you start applying it though you’ll find that this leads to code that is too long; and when you want to change your HTML structure, you have a lot of renaming to do.
What’s better in my opinion is just to give your grandchildren the regular double underscore notation, just with a different name.
If you find that your structure gets too deep, you probably need to make a new component.
Shortening modifier classes?
In BEM, a modifier class is denoted by two dashes. For example, we have a button with the base class c-button
. A large button, which is a variant of the regular button, is denoted with c-button--large
. In your HTML, you would write <button class="c-button c-button--large">My button text</button>
.
In Spatie’s guidelines there is a section on modifiers. The basic idea is that you write modifiers with a “-” and that they have a single responsibility, i.e. they should only modify one thing.
Using this practice leads to shorter HTML, but I think it’s problematic.
The reason BEM is so strong is because of refactoring. When you refactor a project, you are usually searching across large parts of a codebase, searching across many files.
If your class is named c-button--large
and – for example – you want to get rid of it, you can search for that exact string and you’ll find all the parts of the project where it is used, regardless of whether that is in an HTML, Javascript, or CSS file.
Using this method, what are you searching for? A string like -large
? That is pretty much bound to be used in other instances of the code, such as image references or unrelated javascript.
If you write your code like this, you’ve just created a situation for yourself where you made it difficult to refactor the code in the future. Sure, it might be easier to type now. But in the end you’ll find yourself in trouble.
Why BEM is so great is that it provides a clear namespace to evaluate against, whether that is manually or programmatically (i.e. through linters).
Conclusions
I say: let’s not overcomplicate BEM with unnecessary additions that actually make it worse.
Everyone has their own coding style, and depending on what you do, a lot of this BEM/ITCSS logic might not make sense. For a lot of marketing sites, it is simply overkill.
I commend Spatie on open sourcing their guidelines. More companies should do this, including us!
I hope this post is not read as a direct criticism of their CSS guidelines, but as a way to have a discussion about the choices we make.
Subscribe to our newsletter
Receive blog highlights and fresh insights into UX/UI and front-end development.
Leave a comment
Your email address will not be published. Required fields are marked *
3 thoughts on “Overthinking BEM”
29 Aug 2017 at 10:27
30 Aug 2017 at 14:16
30 Aug 2017 at 15:54