BEM for Lunch
Being relatively (4 years) new to the wondrous world that is web development I think I was a little bit overwhelmed when I just started out. Beside the basic stuff I knew, there were so many tools, plugins and frameworks available to further or simplify my work that I didn’t know where to begin.
After 4 years of work, I think I found some middle ground and stick with some best practices that I think are worth sharing. One of them is the BEM methodology. BEM stands for Block, Element, Modifier and is used in the writing of CSS. It helps me daily while building new parts of websites, because it forces me to think about modularity and maintainability. Besides that it helps to keep code specificity at a minimum, which is... well great, but that'll be a topic for another post.
Why BEM?
BEM helps to provide meaningful context to otherwise convoluted code. This in turn helps other developers recognize the logic behind the code you wrote and enables them to add onto, or change it. When working in a team, this is key to writing not only clean, but maintainable code.
Which does what?
The basic components of BEM are quite simple to explain. They look a bit like this .block__element--modifier. When written out they look like this:
Blocks:
A block is an isolated component that can be reused throughout your site. Blocks can be put inside other blocks and may be directly affected by them.
Elements:
These are the component parts of the block that you’re building. Defining elements helps you to add contextual meaning to the parts that make up your block, which leads you to quickly recognize them when you work or copy them.
Modifiers:
Lastly, modifiers. These are a bit odd, in that they can modify both blocks as a whole, but also elements within a block. The syntax remains the same however.
What it looks like
Since this is a relatively abstract description I’ve written a small example to help you wrap your head around this abstraction. This example is written in SASS.
Consider this markup:
We could write this SCSS for it:
Which looks like this when compiled:
As you can see, the generated CSS is not nested and so all the classes that make up the styling of our block and its component parts are on the same specificity level. This is very useful, because it means that we can actually use the cascading nature of CSS in a predictable way.
File structure (extra)
To get the most out of BEM and to help you work in a modular way, I think it is useful to have a file structure that follows the same structured way of thinking. This is a rough setup of my usual SASS folder.
The main file is normally style.scss, a file that everything gets imported into. The first import will always be a type of reset file, which smooths out bumps in browser default behaviour.
After that come my variables and mixins, which can be used throughout the rest of the code, so they need to be in front.
Since I tend to work with font icons and custom fonts often, I like to have all styles related to that in a font.scss file.
Now for the most important file: _components.scss.This file imports all my components which get saved in the components folder. The filename for these components is usually the same as the blockname. This makes it easy to find a component back, even without the use of maps.
After components I tend to import _utilities.scss. This file contains a collection of classes that style one or two attributes at most at a time. As an additional identifier, any attribute set in a utility class could have assigned to it. Since these utilities are imported after the components, and because the use of BEM has made our specificity tree very flat, this probably won’t be necessary.
The last part is _shame.scss. This file contains all the things that couldn’t be styled in a desirable way, either because of code that needed to remain the same, or because of an ugly hack elsewhere in the code. The goal for this file is to be as empty as possible and if at all possible, completely empty.
TL:DR;
BEM is a great way to help you work with CSS in a modular and maintainable way.
Want more?
For a more in-depth read up on the topic I would like to redirect you all to:
CSS Wizardry - BEMIT: Taking the BEM Naming Convention a Step Further