Menu

Permanent Tourist

A personal website by Mark Howells-Mead

Why using BEM for your CSS is a bad idea

I came across the BEM (Block, Element, Modifier) technique for CSS coding today. On reading half a dozen basic introductions to the technique, I saw immediately that the concept is based on weak coding principles, not code simplicity and reusability. (I won’t go deep into technical examples here, as CSS Tricks explains BEM principles more extensively than I can.)

Before I get into any detail, I’d like to say that my style of coding in all languages is based on efficiency and simplicity. I am not a fan of frameworks like Bootstrap. They are great schemes, well-planned and well-programmed, but they are the easiest way to make working on a project massively complicated. I’ll write more on this subject soon.

As part of a complete technical infrastructure plan, the BEM principle is that you should write your CSS and your HTML together, with a level of specificity, so that they work as a unit. You don’t specify parent and child selectors: you use an individual class name for each component.

Have a button containing a subelement containing price information? Define .btn on the button, and .btn__price on the subelement. (Meaning: a price component within a button.)

The HTML for this example would be:

<a class="btn" href="/prices/">
  <span class="btn__price">$9.99</span>
  <span class="btn__text">My product</span>
</a>

You’ll quickly run into code maintenance problems when you find that you need the same styling for that piece of price information when it isn’t contained within a .btn element. Suddenly, you have to make the same definition for .btn__price.list__price.header__price.teaser__price and so on. Four separate class names to speak to what should, in a clean design, be the same component, styled mainly in the same way. With the additional issue that if you add a new parent component type in which a price might be used, you’ll need to add a new CSS rule.

.btn__price, .list__price, .header__price, .teaser__price {
 font-weight: bold;
 font-size: 110%;
 }

So how do you resolve this? Use CSS in the way in which it was intended and don’t try and find your own custom solution to a problem which is already solved.

  1. Define all of the rules which always apply to the price component. Collect them under one simple CSS class name: .price. (For example, all price components should be formatted in bold and have a text size of 110% of the parent component.)
  2. Work out which exceptions apply before you apply them in your code: for example, price components which are in a list shouldn’t be displayed with larger text, but inherit their text size from the list item.

The revised, shorter HTML for this easier example is:

<a class="btn" href="/prices/">
  <span class="price">$9.99</span>
  <span class="text">My product</span>
</a>

…and the simple CSS…

.price {
  font-weight: bold;
  font-size: 110%;
 }

.list .price {
  font-size: 100%;
}

Which of these solutions look cleaner to you? Which is easier to understand? Comments gratefully received here or on Twitter.