Block, Element, Modifier
BEM stands for “Block”, “Element”, “Modifier”. It was originally created at Yandex (the biggest Russian search engine). They wanted a way that could allow the reuse of code across projects and a better understanding of the relationship between the HTML and CSS, giving them transparency and meaning.
BEM is a methodology that helps us designing our CSS using a convention for classes names, making them modular, object-oriented and informative. It is ideal for teams of developers on large projects that might last a while.
“HTML and CSS are easy to code, but hard to code well.”
We have been using BEM for a while, which has demonstrated a helpful approach to structure, organize and scale our frontend architecture. BEM’s syntax can be scary at first, but once you get the hang of it, there are no regrets.
Block
The blocks represent the components themselves, the higher level of an abstraction.
They must be independent to be easily reused and allow the project development and maintenance process to be easier.
A block can be a list, a menu, a form or any other component.
.block {}
We use a hyphen to separate compound names.
.block-name {}
We can also have nested blocks in HTML, such as:
<header>
<div class="logo">
...
</div>
<nav class="navigation">
...
</nav>
</header>
Element
The elements are descendants of a block; they will form the block as a component.
The elements can not be used outside their block.
An element can be a list item, a menu item, a form input field or any other descendant of the block.
.block__element {}
We use two underscores to define elements.
Modifier
The modifiers will define the appearance and behavior of a block or an element. Their use is optional.
If you want the same block to look differently, use a modifier. (e.g. the appearance of a .list
can change depending on a modifier applied to it.)
A modifier can be a horizontal list, a menu modified to look differently on a specific page, a form input field with a particular input style or any other block or element that need modifications.
.block--modifier {}
.block__element--modifier {}
We use two hyphens to define a modifier state.
Naming convention
There is not only one naming convention in BEM; you can see all options here. I like the alternative style proposed by Harry Roberts, one of the firsts to mention BEM in the world.
Reduce your code. Reuse your code
The modifiers are a nice way to take the advantage of reuse in CSS, without specificity mess. Well defined components will make reuse a piece of cake.
Let’s see the example:
See the Pen Reusing code with BEM by Matheus Sales (@sales) on CodePen.
As we can see, we have the standard properties for our button declared in the .btn
class, and the attributes that will frequently be shared across all the buttons.
The specificity comes to the modifiers in a minimum level, changing or adding only the necessary. This way, we have a flexible component that can be easily reused and maintainable.
Sass Nesting
We have been using Sass and really taking advantages of its features. One of its features is nesting, but it can be dangerous sometimes. Because the naming convention is so meaningful, there is no need to nest your Sass when using BEM; this way your compiled CSS will be much smaller and way faster.
/* Good */
.header
...
.header__logo
...
.header__title
...
/* Bad */
.header
.header__logo
...
.header__title
...
Be careful with the nesting structure
We should not nest Elements. The block has elements as dependencies, but elements can not have dependencies. Otherwise, we will be led to be more specific, which is not the goal of using BEM.
/* Good */
.header__link {}
/* Bad */
.header__link__image {}
The usage of the modifiers
The modifiers have to be complementing the base class and not replacing it.
<!-- Good -->
<div class="header">
<a class="header__link">
<h2 class="header__title">Title</h2>
<img class="header__image" src="image.png">
</a>
</div>
<!-- Bad -->
<div class="header">
<a class="header__link">
<h2 class="header__link__title">Title</h2>
<img class="header__link__image" src="image.png">
</a>
</div>
Be careful not to @extend
your base class in your modifiers.
Improve the Comprehension
Good code is not the code you write and only you can read. Good code is the code you write and other people can easily read and understand.
The bigger your projects become, the more your CSS tends to become illegible. While it is not only for large projects, the BEM methodology will make your stylesheets understandable, semantic, simple and more maintainable. Give it a try!