Why BEM matters to the Component Revolution

The Criticism

There are a lot of BEM haters on StackOverflow. The majority of the criticisms deal with how many rules shirk the C of CSS. Cascading was a founding concept in CSS. It makes sense when you’re looking to save bandwidth. Having styles inherit from their parents is a great way to do that. Why would we want to not allow for chained selectors like

.block-class.modifier-class {}

Instead of the the BEM style

.block-class--modifier-class {}

And of course when defending BEM, we usually give simple examples and those simple examples make the argument for BEM hard to see. The usual rebuttal to the “dogma” of BEM is, if I use classes well, I can have reusable modifier classes. And that is true. But middle-aged apps are not simple and even the greatest developer in the world can’t guarantee her teammates will use those reusable classes well. Senior developers have a responsibility to create systems in our code that will not allow junior developers to make common CSS mistakes, opening the door to unintended collisions and inheritance.

BEM prevents the big problems CSS lets you make

This is why BEM is so “dogmatic.” BEM is simply a best practice to simplify complex apps with complex legacy styles. It’s an absolute guarantee that all classes and selectors will only affect the component defined as the Block. If you pick and choose rules with BEM you effectively add a bunch of “ugly” hyphens and underscores to your codebase without actually getting that guarantee.

BEM respects the power of CSS

CSS has always had a lot of power. It’s invariably the piece of the code base that needs changing most often as it’s the most consumer facing. Many of my colleagues in the startup world agree that polished CSS is the mark of a real contender versus a team playing catchup. You could have the ugliest backend code and no investor would notice. (As long as it’s speedy).

The problem becomes the style of an app quickly becomes rather kludgy. Developers should not have to make design decisions on the fly. Having a lassie-faire policy towards CSS will grind productivity to a halt as we layer level after level to quickly finish a ticket.

Simple, don’t let backend developers code…right?

We may decide to split the front end and backend teams and refuse to let backend folks touch CSS. This works without BEM until you hire a frontend developer who codes differently. Some guidelines are clearly in order. So the question then becomes, to what end?

If the end is to componentize the front end and present a set of components to the backend team to use as they need, well BEM offers all the rules needed to do this well and no more. Specifically CSS inheritance is dangerous in a culture of plugins and packages. Plugins end up setting global styles, leading to overwriting rules. I’ve discussed why this sucks in another article. But it happens in non-plugin code as well. The second problem is hierarchy is kind of arbitrary. Which takes precedence in CSS, an id or a nested class? I don’t know off hand and no one ever should, it’s arbitrary. Same goes for tag names in CSS and chaining. It’s we well done in modern browsers but still arbitrary and not worth memorizing. BEM makes decisions for us to make the path to the end of a component easier. It’s strict adherence to the single class that namespaces itself with dashes and underscores allows us to track down rules faster, know, not hope that changes don’t collide elsewhere on the site.

Conclusion: BEM is for apps that have come to need it

Perhaps part of the pushback from the community has to do with aesthetics. I understand that. I don’t like underscores. Frankly, I’m a fan of camelCase, even if html and css is not case sensitive. And BEM can be a bit less DRY than chaining or reusing “utility” classes. These are fair criticisms. But in an app that has outgrown it’s startup skin, BEM provides the kind of structure to make sense of an every growing app. I urge you to apply BEM principles to a complex part of your app. You’ll find that the moments of unDRY code are forgivable in favor of developer happiness and ease in refactor.

It also gives us a foolproof way to refactor and know, not hope, that our changes aren’t clobbering some other part of the site. There are still many questions that haven’t been answered about BEM best practices. This BEM refactor series hopes to investigate those questions more deeply.

Thanks for reading. 
 — Lawrence Whiteside