Johan Ronsse
22 Aug 2017

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.

Johan Ronsse

About the author: Johan Ronsse is an interface designer who is trying to find the balance between aesthetics and usability. He tweets as @wolfr_2.

4 thoughts on “Overthinking BEM”

Author Avatar

Hey Johan,
glad you took the time to read our guidelines.

The goal of the grandchildren is to clarify the logic of a component, rather than follow the HTML structure. For a ‘news’ module, we could have ‘news__item’ children that each have a ‘news__item__title’, besides a generic ‘news__title’ on component level.
Sure, we’d better use a new subcomponent or regular child with better naming.
But sometimes a component is just too small to dissect or you just want to get going without looking for the right words. No harm done if you stick to max. 3 generations.

The concept of shorter modifiers (and variations) was borrowed from Envato (https://webuild.envato.com/blog/chainable-bem-modifiers/) and Viget (https://www.viget.com/articles/bem-sass-modifiers) and has worked out pretty well for our scale of sites & apps.
It doesn’t make BEM worse for us; in our experience it’s more readable and usable.

The argument of refactoring is actually not something we struggle with in real-life usage.
– HTML and Vue templates: since a ‘-large’ class alone has no effect, you’d have to namespace it anyway in code with ‘class=”button … -large”‘, making it searchable with a regular expression. Larger components have their own template, so we know where to look.
– Same setup for CSS: you’d look in ‘button.css’.
– That leaves us with scattered state modifiers set by server or client script, eg. ‘-active’ in ‘class=”button -active”‘: I’ve don’t see a scenario (yet) where we had to remove these site wide.

At this point we spend way more time on building new stuff than on refactoring entire code bases (fingers crossed!); hence the choice for more readable class chains and less repetition.

Author Avatar

I really don’t think it is a problem the way they are writing, as long as they write always the same.
I agree that might be easier to find “–” instead of “-“, but still as Willem said there are other ways to find and still get the results you want.
For me, the most difficult part when dealing with BEM is when I must decide to segregate a smaller part of the component in another component or leave it as a child.
Thanks for sharing your thoughts.

Author Avatar
Jordy

Keep it simple stupid 😉

Author Avatar
Rodriguez

I am surprised to find this barely useful blogpost in the css weekly. The “solutions” don’t have any examples and there’s only 2 cases. Really? You only found two things to talk about misusing BEM?

You could make this better by stating examples for solutions too.
‘component__grand-child’ instead ‘component__element__element’ etc. Willem Van does a good job of explaining the goal here.

Leave a reply

Your email address will not be published. Required fields are marked *