BEM - A CSS Naming Convention
Published: 2020-07-10 00:42:13

---
title: BEM - A CSS Naming Convention
published: true
description: A brief introduction to BEM
tags: 
//cover_image: ![BEM in HTML](https://dev-to-uploads.s3.amazonaws.com/i/0pay145elw2xi17w5mo7.png)
---

#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.