What is BEM?
BEM is an acronym for Block, Element, and Modifier and is a methodology for creating reusable CSS. BEM works by providing a pattern for naming components that makes the relationship of a components style classes to the markup more obvious. For example, take a navigation component on a web page. Some items that might be included are a nav container, a list, and list items.
Blocks
Since we're using the nav component and know that we have a nav container, list, and list items, we can use BEM to help us give these items some meaningful class names. BEM's naming structure follows a pattern where blocks are named things such as nav
, container
, or header
. Blocks are top-level items on a webpage (or screen if you're working on mobile devices). The best way to figure out whether an item is a block is to determine if it is meaningful on its own. For example, a nav
or button
item is meaningful on its own. You know exactly what these items are without needing any extra context. If you're perusing some css and see .nav
then you don't really need any other context. You can tell exactly what a nav is just by reading the class name.
Elements
Elements are named using a double underscore such as nav__list
, container__title
, and button__submit
. Elements are part of a block and do not have standalone meaning. A good example to help convey what this means is to think of a list item. An li
on its own has no standalone meaning. What is it tied to? Where does it go? If you see li
in CSS then you have little to no idea of where the li
is located in your markup and you have no idea how many li
elements on the page will be affected if you edit the CSS. However, if your li
is named navList__item
then suddenly this element has meaning. It is important to note here that blocks can have many nested elements, but blocks cannot be nested within an element. This is due to the fact that blocks must be meaningful on their own.
Modifiers
Modifiers are the smallest units in BEM and are used to describe the behavior, states, or appearance of an item. Take the nav list items, these could have modifiers for color or hover. In BEM this would look something like navList__item--blue
or navList__item--hover
. Note the two dashes. This is how to denote an attribute in the BEM naming convention.
Putting it all together
Now that we know the basics of the BEM naming convention, let's see what this might look like. Using the nav example discussed throughout this post the markup might look like this:
<div className="nav">
<nav className="nav__container">
<ul className="nav__list">
<li className="navList__item--blue">I am blue!</li>
<li className="navList__item--red">I am red!</li>
<li className="navList__item--hover">I have a hover state!</li>
</ul>
</nav>
</div>
Now that we know what our HTML looks like, we can design some CSS classes. Based on the names created, the CSS may look something like this:
/* Block */
.nav {
text-decoration: none;
background-color: white;
color: #888;
border-radius: 5px;
display: inline-block;
margin: 10px;
font-size: 18px;
text-transform: uppercase;
font-weight: 600;
padding: 10px 5px;
}
/* Element */
.nav__ul {
background-color: white;
color: #fff;
padding-right: 12px;
padding-left: 12px;
margin-right: -10px; /* realign button text padding */
font-weight: 600;
background-color: #333;
opacity: 0.4;
border-radius: 5px 0 0 5px;
}
/* Modifier */
.nav__li--blue {
color: blue;
font-size: 28px;
padding: 10px;
font-weight: 400;
}
/* Modifier */
.nav__li--red {
border-color: #0074d9;
color: white;
background-color: #0074d9;
}
/* Modifier */
.nav__li--hover: hover {
border-color: #ff4136;
color: white;
background-color: #ff4136;
}
Imagine that the CSS was the first thing you looked at in a project. If you saw CSS like what's above, it would be easier to read those classes and know exactly what it is they're supposed to be styling. This is one of the biggest benefits of BEM. BEM allows you to design your code in such a way that both your HTML and CSS make sense separately, as well as together.
Wrap up
Keep in mind that this isn't a perfect example, it was designed in a way that made the most sense to me. That is exactly how BEM should be used. There is not a one-size-fits-all approach here. If you, or your team, prefer different class names and structure, then use whatever seems best suited to your project. The most important part here is keeping the code clean, readable, and maintainable. When your CSS makes sense, it's much easier to go in and make edits and know exactly what it is that you are changing without having to fight with a bunch of different cascading rules.
Top comments (12)
You're not wrong, the modifier is just the -- at then end of the name though. I just used simple class names for the purpose of demonstration. The listItems are still elements, just elements with a modifier.
I like BEM because it makes CSS feel more like you're working with Classes and Inheritance even if its just for syntax purposes. I prefer using Sass with the SCSS syntax because it feels better organized as well. Below is how CSS would look like using SCSS
I actually plan to have a future post with SASS and SMACSS!
👏👏👏👏
Nice description, but it sure makes me wonder why people are constantly fighting CSS instead of just using it the way it handles best. What's the appeal of writing HTML like it's 2000 again?
Not sure what did you mean here by
What's the appeal of writing HTML like it's 2000 again?
. Could you please elaborate?In the early days of HTML, when CSS was not a thing and, later on, when CSS was very new and unreliable and developers were just not used to it yet, the way to style your website was through HTML tags. The advantage of CSS is that you can pull styling out of the HTML into a different document and set up axiomatic rules for how things should look on the whole website. These days, however, developers have gone back to the old style, but they've replaced tags with classes. All the styling is put in the HTML document and only some generic rules are described in CSS, effectively making for a more verbose version of what we already had in the past. I'm wondering why that is. There's clearly some appeal to this very explicit styling aproach of telling each element what it should look like, but I fail to understand what could possibly outweigh all of the benefits of a mostly axiomatic CSS structure.
This makes a lot of sense, definately going to implement it in my next project!
Great I love a naming convention, CSS can be actually madness with a zillion classes out there. I honestly feel the double underscore a little too much but I might get used to it.
Inuitcss + bem = perfect combination. :D
Good description