a quick look at BEM and why it’s useful

I try to use BEM where I can and when it’s appropriate. That last piece is important. BEM is not appropriate in every scenario. I’m not preaching that everyone should go out and BEM, SMACSS etc. all of their code. Classname standards are important though and should always be given time and consideration. They will make your code easier to read for newcomers to your source, especially if you are using a commonly used standard.

What is BEM?

/* THE CSS */
.btn {} //block
.btn__txt {} //block element
.btn--lg {} //block modifier
.btn__txt--red {} //block element with modifier
<button class="btn btn--lg">
<span class="btn__txt"></span>

BEM stands for block, element, modifier. What are these three components?

  • block — a block represents a high level component that may comprise of many smaller elements. It can be rendered in isolation or with others.
  • element — an element is a building block of a block denoted by two underscores. It has a dependency on it’s block. In some cases a mutual dependency if an element provides important context for a block.
  • modifier — modifiers can be used to express different aesthetic effects and states of elements and blocks. These are denoted by two hyphens.

An analogy? Maybe a sports team(please suggest better).

  • The team is the block.
  • A player is an element.
  • A players’ position could be the modifier.
.team {}
.team__player {}
.team__player--forward {}
.team__player--defender {}

BEM aids with readability for not only your CSS, but your markup too. If I was new to a repo and saw the following;

<button class=”btn btn--lg”>
<span class="btn__txt btn__txt--red">push me!</span>

I assume from reading the markup that I have a large variation of a button with red text saying “push me!”.

It’s likely there are variations for small and other text colors. If not, it is clear to me how I would go about introducing them to comply with the current style. The element hierarchy/dependency of a block can also be easily learnt from reading the source.

The features of BEM promote flat specificity. They allow us to tackle complex specificity, in some cases eradicating it altogether.

.btn .txt {} => .btn__txt {}

There may be scenarios where you can’t quite BEM it. You’re unable to escape levelled specificity or something doesn’t quite sit right. Don’t give up at the first attempt. The power of BEM is that it makes you carefully consider your markup and CSS. One blocks rule should not interfere with nor override another. It may be that you need to introduce a new element to your block or think about adding a modifier to a sub-block. In my honest opinion, try your best to avoid sub-elements.

BEM can get quite opinionated when not so simple use cases arise. That’s one of the pitfalls with BEM. There is no strict right or wrong. Knowing when it’s necessary and how to use it effectively is BEMs trickiest aspect.

However, at the very least, attempting to use BEM or any classing standard for that matter is a step in the right direction and can improve your code leaps and bounds if you’ve got into a bit of a state with your CSS and markup.

For a high level intro, that’s pretty much all you need to know in order to get started with BEM.

Working observations

It’s when you start working with BEM and tackling real projects that questions regarding BEM usage arise.

Many modifiers, much ugliness

What if you have several modifiers for a block or element? You don’t want to end up with several large bloated classnames. If the modifiers are small then do you need to write a big extra class for them? How about the following modifiers?

.btn.small {}
.btn.medium {}
.btn.large {}

Is this right or is this wrong? It’s just a little modifier and we save having to write long classes in our markup.

Ideally, we shouldn’t be doing this. Because the classes “small”, “medium”, and “large” offer no context, they could get altered if we say wrote CSS for those classes elsewhere.

Say we had the following(unlikely) CSS;

.small { background-color: red; }

Now all of our small layout panels are red and we don’t want that. But, because our class isn’t specific enough in our markup, we now have red panels(unhappy face).

.btn.small { background-color: green; }

We could add a specific “background-color” declaration to our nested classes but now it’s getting messy.

This is why carefully determining our elements and modifiers is important. Consider this;

.btn--small { height: 10px; }

This means instead of our previous markup which could be;

<button class=”btn small”></button>

We now have;

<div class=”btn btn--small”></div>

This is nice with small convenient examples like “.btn”. This get’s bloated much quicker when we have larger block names. Consider;

<div class="super-block small red"></div>
/* BEMifying to */
<div class="super-block super-block--small super-block--red"></div>

We are only using two modifiers and our classes are becoming rather bloated. They don’t have to though. We can change them by defining appropriate abbreviations. How about the following?

<div class=”sb sb--sm sb--red”></div>

That now has a smaller footprint than our original markup! And still retains meaning if we understand the abbreviations.


I write very little CSS without using a preprocessor. Personally, I’m a fan of Stylus. When using BEM, preprocessors can catch you out sometimes if you’re not careful.

For example, consider nesting. As I’m picturing the DOM structure in my head whilst writing my preprocessor code, I’m instinctively thinking of using nesting to write my classes as I picture the structure. If written in haste, I might write something like;

.btn {
.btn__txt {}

This code, would actually go against our BEM ideals producing

.btn .btn__txt {}

The visual cues that preprocessor nesting provides for element structure can give an almost false confidence as to your CSS being lean, specific and robust. There are times when you could get caught out, never mind the unnecessary bloat in your CSS that is introduced. (Consider the earlier discussion about small modifiers introducing unnecessary CSS overrides for background color)

Luckily, the ampersand operator comes to the rescue as long as you remember to use it.

.btn {
&__txt {}

If you are writing vanilla CSS, or non-nested [insert flavor of your choice] syntax, you’re unlikely to fall into this trap whilst trying to keep your specificity as flat as possible.

.btn {}
.btn--red {}
.btn__txt {}
/* NESTED */
.btn {
&--red {}
&__txt {}

How could we reduce the complexity of looking at nesting whilst making sure we keep our code clear and concise with a preprocessor? Most preprocessors have some form of mixin functionality. Leveraging this can really help with keeping nested code legible. Consider the following Stylus code;

red = {
color: red;
txt = {
font-size: 10px;
define(‘content’, lookup(elName))
define(‘content’, lookup(modName))

.btn {
padding: 5px;
+mod('green') { // BLOCK MIXIN
color: green;

This would output;

.btn {
padding: 5px;
.btn__txt {
font-size: 10px;
.btn--red {
color: #f00;
.btn--green {
color: #008000;

Understandably, not everyone will be using Stylus, but the same concept can be adapted to work with the preprocessor of your choice, feature permitting.

Nested elements

How do I tackle nested elements?

<nav class="nv">
<li class="nv__item">
<a class="nv__item__link">LINK</a>

Not quite.

You’re looking to avoid scenarios like this ideally. In this case, nav items and nav links should both be their own elements.

<nav class="nv">
<li class="nv__item">
<a class="nv__link">LINK</a>

If you needed to be specific about a link within an item. You may look to introduce a modifier to tackle this.

<nav class="nv">
<li class="nv__item">
<a class="nv__link nv__link--header">LINK</a>

You may decide that a link is not even an element of nav and you want to just introduce modifiers for links within the nav.

<nav class="nv">
<li class="nv__item">
<a class="link--nv">LINK</a>

That’s one of those fun/tricky parts of BEM, emphasising there is no 100% right or wrong way when working with BEM.

That’s it!

A quick look at BEM. As mentioned above, not appropriate in every scenario but can really aid in making your source user friendly. As always feel free to leave a note, suggestion or tweet me @_jh3y!