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.
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:
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.
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
Using this method, what are you searching for? A string like
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).
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.