Software development

Tech Pick of the Week: BEM

Frontend Developer

Let’s face it. In large projects, CSS is a mess. The larger the project, the bigger the mess. There seems to be no way to avoid it – it just happens. Traditionally speaking, there are two schools of thought when it comes to organizing CSS: a) you prefix everything with a parent selector, e.g. .main-nav .nav-item or b) you use several classes at once, e.g. .nav-item.large. The worst case scenario is a project that incorporates both of these, and uses overly specific selectors to override styles in some cases – in other words, pretty much every single larger project you’ve worked on.

The reasons for bloat are many, but, personally, I think the very structure of the cascade is what make Cascading Stylesheets so vulnerable to abuse. The idea of calculating the most powerful style for a given element, going through generic element selectors, then class selectors, ids, compound selectors and so on is much more complicated than it needs to be. However, since there is no notion of scope in CSS, we need a way to emulate them. This is where BEM comes in.

BEM stands for Block, Element and Modifier. It is a frontend methodology originally conceived by the guys at Yandex, and later on adopted and honed by many. There was a really nice post by Harry of CSS Wizardry on how and why he uses the methodology. In summary, he uses CSS classes for everything, and all elements have classes that describe their relationship with others. Here’s the naming convention:

.block
.block__element
.block--modifier

The block could be something like .post. Inner elements, like the title would then have classes like .post__title, .post__content and so on. Different kinds of posts would be denominated with modifiers, for example .post--special. This naming scheme is incredibly easy to comprehend and to adopt. It is also quite flexible. You can well use modifiers for inner elements as well, along the lines of .post__tag--green and .post__tag--blue. To get a better idea of the naming, please read through the aforementioned CSS Wizardry post.

I used this naming scheme in a project not long ago, and here are my thoughts.
There are a lot of good qualities to the methodology. First and foremost, it keeps your CSS very manageable. All styling will be at the global level (no deep selectors) and well namespaced, so there should be no accidental overriding like with .title and similar classes. When using SASS, we can easily split the styles into modules based on the Block.

The notation is also remarkably expressive. It helps you – and other developers in the project – figure out what the selector means. If you see a selector for .news__title--large, you immediately know that we’re in the News block, targeting the Title element and specifying styles for a Large variation of the element.

When used together with SASS, the modifier pattern truly comes to life. We can declare the main style for the block and extend it in the modifier variants like so:

.post__tag {
  display: inline-block;
  padding: 5px;
  color: #fff;
  background-color: #666;
}
.post__tag--green {
  @extend .post__tag;
  background-color: #060;
}
.post__tag--skyblue {
  @extend .post__tag;
  color: #222;
  background-color: #ccf;
}

So what’s the downside to all this? Well, everything in the HTML has to have a (long) classname. You’ll end up with something like the following:

<div class=”meta”>
  <span class=”meta__author”>Ossi</span>
  <time class=”meta__pubdate”>October 14th, 2013</time>
</div>

If you consider the structure in CSS, though, you understand that it no longer matters whether the .meta__pubdate is a div, a span or a time element. Also, just looking at the CSS you see that it is an element within the .meta block.

If you think BEM adds a lot of redundancy to the HTML, I suggest you put these things into perspective. We live in a time where mobile phones are powerful enough to comfortably run Gmail, Facebook and similar web apps. The length of a classname is no longer the main concern when it comes to performance. I’d argue that the amount of modular reusability and sheer expressive power you gain from using this kind of naming scheme far outweighs the possible savings in markup kilobytes. Besides, as Nicole Sullivan points out in her slides, with the traditional way of using descendant selectors, you will actually easily end up with so much more repetition in the CSS that the outcome of using BEM is actually less data to load!

The bottom line is that I find using the BEM methodology to be a solid way of encouraging modular thinking in frontend development. It resolves a great many of the issues with large stylesheets, and pretty much the only downside are the longer-than-usual class names in the markup.

Frontend Developer

Ossi is a web developer specifically fond of the frontend and user interfaces.

Viewed 786 times