DEV Community

Charissa Johnson
Charissa Johnson

Posted on

BEM - A CSS Naming Convention

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)

Collapse
 
charissayj profile image
Charissa Johnson

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.

Collapse
 
salhernandez profile image
Salvador Hernandez • Edited

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

.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 */
    &__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;
        }

    &__li {
        /* Modifier */
        &--blue {
            color: blue;
            font-size: 28px;
            padding: 10px;
            font-weight: 400;
        }

        /* Modifier */
        &--red {
            border-color: #0074d9;
            color: white;
            background-color: #0074d9;
        }

        /* Modifier */
        &--hover{
            &:hover {
            border-color: #ff4136;
            color: white;
            background-color: #ff4136;
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
charissayj profile image
Charissa Johnson

I actually plan to have a future post with SASS and SMACSS!

Collapse
 
johannarlee profile image
johanna

👏👏👏👏

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

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?

Collapse
 
sharvilak11 profile image
Sharvilak

Not sure what did you mean here by What's the appeal of writing HTML like it's 2000 again?. Could you please elaborate?

Collapse
 
darkwiiplayer profile image
𒎏Wii 🏳️‍⚧️

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.

Collapse
 
emmaliefmann profile image
emmaliefmann

This makes a lot of sense, definately going to implement it in my next project!

Collapse
 
cdsaenz profile image
Charly S.

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.

Collapse
 
landb profile image
Branko Stancevic

Inuitcss + bem = perfect combination. :D

Collapse
 
miteshkamat27 profile image
Mitesh Kamat

Good description