See all writing

How BEM makes naming CSS classes a doddle

There are only two hard problems in Computer Science: cache invalidation and naming things — Phil Karlton

14 months ago I began my journey into web development and in that time I’ve read up on a lot of different methods of how to write efficient code, improve my file structure and generally better organise my projects. Doing this helps ensure anything I work on is easy to maintain, scalable and efficient.

Naming conventions are one of the more trickier skills to master when you’re a developer, because you can quite easily run out of names for the parts of the website you’re building and end up with horrific names for your elements like:

css
.menu {
  style: cool-styles;
}

.menu-list-items-wrapper {
  style: cool-styles;
}

.menu-list-items-inner-wrapper {
  style: cool-styles;
}

.menu-list-item {
  style: cool-styles;
}

.menu-list-item-2 {
  style: cool-styles;
}

.menu-list-item-mobile {
  style: cool-styles;
}

You get the idea how this could get out of hand very quickly.

A CSS/SCSS naming convention I was shown when I started at Bluegg was BEM.

BEM stands for Block, Element, Modifier and if you’re like me and still in the early-ish stages of your development career, this could point you in the right direction and show you how to better structuring your code for future developments. 

Okay, how do I use BEM in CSS?

BEM’s objective is to divide the overall website into small reusable components, which in turn allows you to easily organise and find your components (blocks).

Let's start with creating our block, and let's imagine our block is a house. 

html
<div class="house">

</div>
css
.house {

}

Nothing groundbreaking at this moment in time, but next were going to start using the element part of BEM, to break our block down.

html
<div class="house">
  <div class="house__roof">
  </div>
  <div class="house__walls">
  </div>
  <div class="house__garden">
  </div>
</div>
css
.house__roof {

}

.house__walls {

}

.house__garden {

}

The roof, walls and gardens are all child elements within the component/block and should only be used within the house component. When you want to name an element within a block, you denote this by using two underscores followed by the name of your element.

The final piece of the CSS BEM model is the modifier, your modifier is derived by adding two hyphens followed by the modifiers name. 

html
<div class="house">
  <div class="house__roof house__roof--roman-tiles">
  </div>
  <div class="house__walls house__walls--clay">
  </div>
  <div class="house__garden house__garden--front">
  </div>
</div>
css
.house__roof--roman-tiles {

}

.house__walls--clay {

}

.house__garden--front {

}

"But now I want a bigger house"

You aren’t limited to only using a modifier on a element, you can also use them on your blocks, so if I wanted the house to vary in size, I can add a modifier to the block like so:

html
<div class="house house--big">
</div>
css
.house--big {

}

.house--small {

}

Using BEM in your CSS is a great way to structure and ‘future proof’ your code for projects that will scale up over time. It unites the development team under one CSS naming convention and allows us create new blocks, elements or modify classes with ease, as all markup is clearly labelled and broken down into easy to find modules.

What about BEM and SCSS?

If you’re a dev starting out and you haven’t heard of Sass/SCSS, change your life with Scss here.

BEM and SCSS go together like your favourite thing 1 & your favourite thing 2. 

The markup would stay the same as above but our styles have now changed a bit.

Being able to break up your style sheets in modules and nest your elements and modifiers under one class compliments the BEM model perfectly.

scss
.house {
  &__roof {
    &--roman-tiles {
      
    }
  }

  &__walls {
    &--clay {
      
    }
  }
  
  &__garden {
    &--front {
      
    }
  }

  &--big {
    
  }
  &--small {
    
  }
}

Applying the logic as above, you can now take the house block and give it its own SCSS file within your project. If you gave the house block its own partial markup file too, you would then have a reusable block/component you can place anywhere on your website.

See the Pen BEM by Jack Evans (@eagleeyejack) on CodePen.

And like that, a modern piece of art has been created right before your eyes. You can send all bids for the work to my twitter @jackdavidevans

The CSS BEM / BEM SCSS combos can cause a headache…

It’s BEM and not BEEM for a reason.

So let’s say you buy my artwork above and I spend the money on a loft conversion and a new chimney for my house.

A chimney element only belongs on the roof, so do you now add this new chimney element into the already existing roof element?

css
.house__roof {

}

.house__roof--roman-tiles {

}

.house__roof__chimney {

}

.house__roof__chimney--slate {
  
}

The short answer is no. I would argue that the chimney would now become its own element within the house block like so:

css
.house__roof {

}

.house__roof--roman-tiles {

}

.house__chimney {

}

.house__chimney--slate {
  
}

I would then put the new chimney element on the roof in my markup.

Stretching this BEM CSS house analogy as far as I can, what about if I want windows for my house?

I could create a new element for window within my house block but the types of windows I want for my house could vary quite a bit, especially if I want to extend my house further on down the line. I might want skylights, sash windows, bay windows…

But didn’t you just say you could create a new element and include this in the markup? 

Couldn’t you just add modifiers within the element and it’d all be okay? 

scss
.house {
  &__window {

    &--skylight {
      
    }
 
    &--sash {
 
    }
 
    &--bay {
 
    }  
  }
  &__roof {

  }
  &__walls {

  }
  &__garden {
  
  }
  &__chimney {

  }
}

When I'm cleaning windows

The issue is when I come back in a year to clean my windows (run with me here), I want to be able to find them all as quick as possible and reduce my cleaning workload.

In order to do this, I would make the window element it’s own block and then include that into my house markup.

The benefits of this is if I had to build another house that had a different structure, but the window designs were staying the same, I could use this new window block and save myself a lot of work making new windows.

html
<div class="house">
 <div class="house__roof">
   <div class="window window--skylight">
  
   </div>
 </div>
</div>
scss
.house {
  &__roof {
 
  }
  &__chimney {
 
  }
}
 
.window {
  &--skylight {

  }
}

Doing this I now know there’s only one window class to change in one location (using SCSS) and once I’ve cleaned/changed one window, no matter how many different types there are, they’re now all clean/changed.

So I now know to how to BEM, what next?

I’ve learnt there’s always something new to be learning when it comes to web development and if you’re interested in reading something a bit more cutting edge than BEM, check out Matt’s blog here on Gatsby.js, Craft CMS & Netlify.

Any questions about what to learn next if you’re starting out in web development? Tweet us.