How to BEM

What you should consider when writing maintainable CSS


Prefix

This article was lying around in my draft box for too long. I always tried to learn new things so I could create the ultimative guide that would pull your socks off, but actually other people work faster in producing high value content than I ever could. But still I want to share some learnings I had and even if now eventually the time of Webcomponents has come this article can hopefully help some of you in managing your CSS on a leven you could easily reuse it in whatever context you’re using it.

Once upon a time …

About 6 years ago I wrote my first line of CSS. I think it was something like

body div#content h1 {
postion: absolute;
top: 100px;
left: 20px;
font-size: 42px;
color: black;
}

I can only imagine how powerful god felt when he created the earth but I guess I felt pretty much the same at this moment.

Today I know that what I did then in the original context was pretty shitty to be honest. But the reason was I didn’t knew any better and sadly my professor who taught me didn’t knew either. Luckily CSS ( like any other aspect of the web) has evolved and the community showed the right way to go. Now some years and I guess a bazillion lines of CSS later, I can only shake my head about what things I did there in the past.

OOCSS

Well if you work a lot with CSS nowadays you should definitely heard of Object Oriented CSS or at least SMACSS. Long story short, both tell you to think about how you want your selectors to look like to prevent depply nested and specialized CSS rules. I personally like the OOCSS approach a lot as if it get’s used correctly you can create good working CSS libraries that help you keeping the overlook of you Stylesheets. But at some point I realized I am loosing readability and clear affiliation of classnames in bigger projects. For Example:

<div class=”comment promote”>
<p class=”title”>Written by <span>John Doe</span></p>
<p class=”body”> … </p>
<a href=”#” class=”reply”>Reply</a>
</div>

I needed various version of comments. And some comments would look special for example when they are promoted for any reason. In this case above it’s very hard to see what this block is really about ? Is it a comment or a only a promotion that should look like a comment … and believe me, 3 month later you won’t remember exactly as your brain had to work on other code.

Enter BEM

BEM stands for Block — Element — Modifier
It is an approach in helping you to organize special UI-Blocks into something like widgets, components or however related pieces of HTML with informative classnames.

Block — The main classname should be the identifier for a “component” (ex: .article)
Element — This is a html element with a look that will have to work in the context of the parent block element. An Element is usually named with the parents classname following two underscores and the elements name. (ex: .article__title)
Modifier — The modifier describes a specific situation an element or block is in. The modifier should css wise only be used to alter the appearance. Also the modifier should ONLY be used accompanying the elements classname. You would write it using to dashes. (ex: .article — sponsored)

Well, so much for the theory. Let’s look at an example:

<div class=”article”>
<h2>How to Bem</h2>
<p class=”summery”>…</p>
<div class=”meta”>
<figure class=”author”>
<img src=”…” alt=”…”>
</figure>
<p class=”authorname”>…</p>
<a href=”…”>Other Articles</a>
</div>
</div>

Codeblock without BEM. I have seen something very similar quite often to be honest. So for me some questions rise up.

  • How is the meta block related to the article ?
  • Can it be used somewhere else ?
  • What if I add an extra anchor to the meta block ?
  • Could I have already used the classnames summery or authorname somewhere else ?

Actually I have to look at the CSS to understand whats really going on. Very often its the case that you will have very distinctive long css Selectors to maintain the difference. For example:

/* In css related to my sidebar I defined something like */
.meta {
background: #BADA55;
...
}
.author {
...
}
/* In a later section I have to overrule certain values */
.article .meta {
background: none;
...
}
.article .meta .author {
...
}

You really have to search through the css file to see that there is a difference. Certainly you will know your css very well when you wrote every line of code on your own but can you still remember after not looking at a certain project for half a year ? ( I couldn’t and it cost me a lot of unpaid time to make some updates )

Now let’s look at the same html with BEM classes.

<div class=”article”>
<h2 class=”article__title”>How to Bem</h2>
<p class=”article__summery”>…</p>
<div class=”article__meta”>
<figure class=”author author—article”>
<img src=”…” alt=”…”>
</figure>
<p class=”article__authorname”>…</p>
<a class=”article__meta__more” href=”…”>Other Articles</a>
</div>
</div>

Well you see the main difference immediately. The Markup is much more verbose than before. But you also immediately see how certain elements are related to each other. This brings us a huge benefit on the CSS Side as we don’t need to nest most selectors which makes the CSS better readable and faster. ( Yeah I know… CSS Performance is the least important issue but an easy win is awesome anyway )

/* Somewhere on top I defined certain Elements I'll use on the page */
.author {
...
}
/* In my Sidebar I use a meta block */
.sidebar__meta {
...
}
/* In a later section I define my article related values */
.article__meta {
..
}
.author--article {
...
}

And now imagine you would read the previous CSS and this one the first time ever without knowing the markup. I think it’s very obvious that the latter example is much more self-explanatory.

Extending BEM

Sometimes you don’t want to create a modifier or element or special class or whatsoever when it doesn’t make sense or is just to verbose. Feel free to extend this pattern with personal rules you want to use through the project. For example I never use a modifier to show an active state. I prefer to verbal prefix those things. For Example:

<li class="nav__item is-active">...</li>
...
<form class="form has-errors">...</form>
...
<button class="btn btn--prominent js-doSomeStuff">...</button>

Conclusion

This is only a very simple example of BEM. Please note down that this isn’t the solution for everything and it’s very easy to overuse this approach. You’ll have to figure out when it makes sense to use the pattern. For me using BEM in larger projects was a huuuuuuge benefit when working in a team or touching certain parts of code again after a few months.