BEM in CSS: A Structured Approach To Write Scalable & Maintainable Styles

BEM in CSS: A Structured Approach To Write Scalable & Maintainable Styles

What is BEM?

In short, BEM is a popular methodology for naming your CSS classes.

BEM stands for Block, Element, Modifier. It's an approach to writing CSS styles which allows developers to create reusable components that are easy to maintain and debug. It also helps create consistent styling across applications and websites by promoting the use of reusable classes and code.

BEM naming convention boils down your CSS class names into 3 parts -

  1. Block

  2. Element

  3. Modifier

It means that every class name should either represent Block, Block Element, or Block Element Modifier altogether.


Let’s understand this with an example.

Below is the HTML & CSS code for Navigation Bar without using BEM 👇

<!-- Navigation bar markup w/o BEM -->
<nav>
  <ul class="nav">
    <li class="nav-item active">Home</li>
    <li class="nav-item">About</li>
    <li class="nav-item">Contact</li>
  </ul>
</nav>
nav {
  width: 100%;
  height: 5rem;
  background: teal;
}

.nav {
  height: 100%;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.nav-item {
  font-size: 1.5rem;
  text-decoration: normal;
}

.active {
  text-decoration: underline;
  font-weight: bold;
}

Below is the HTML & CSS code for Navigation Bar using BEM 👇

<!-- Navigation bar markup w/ BEM -->
<nav>
  <ul class="nav">
    <li class="nav__nav-item nav__nav-item--active">Home</li>
    <li class="nav__nav-item">About</li>
    <li class="nav__nav-item">Contact</li>
  </ul>
</nav>
nav {
  width: 100%;
  height: 5rem;
  background: teal;
}

.nav {
  height: 100%;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

.nav__nav-item {
  font-size: 1.5rem;
  text-decoration: normal;
}

.nav__nav-item--active {
  text-decoration: underline;
  font-weight: bold;
}

Here,

.nav : block

.nav__nav-item : block__element

.nav__nav-item--active : block__element--modifier

Note that block is a top-level entity, block & element are separated by 2 underscores, and element & modifier by 2 hyphens / minus signs.

Block

A standalone entity that is meaningful on its own. In our example code, it is nav. button, header, container, menu, checkbox, input are some other examples.

Element

A part of a block that has no standalone meaning and is semantically tied to its block. In our example code, it is nav-item. menu-item, list-item, checkbox-caption, header-title are some other examples.

Modifier

A flag on a block/element. Use them to change appearance or behaviour. In our example code, it is active. disabled, highlighted, checked, fixed, size-big, color-yellow are some other examples.


There is no hard rule that you need to use BEM methodology. But using this solves the issue of duplicating the class names when your web application grows larger. Imagine if you are working in a team and one of your team members has written a new class, say .container, which already exists. This might break the functionality or style of other elements.

Of course, other approaches can solve problems occurring to class name duplication, such as Styled Components & CSS Modules in React, and View encapsulation in Angular. But BEM is here to help us write meaningful and maintainable class names, and also avoid duplication.


Advantages of using BEM methodology -

  • Just by looking at the class name one can figure out, to which element the CSS class belongs.

    • For instance, a BEM-structured class name like button--primary would clearly denote that this is a primary-styled button element, as opposed to a generic class name such as button-green.
  • By giving meaningful element/modifier names, we can easily inspect CSS & identify whether there are existing classes for the component (block) before writing a new class.

  • Makes refactoring of CSS easier. You don't have to fear deleting a class from your CSS file since you will be sure that no other component will be using the same class name in your project.

  • Improves code readability & avoids duplicating class names.

Disadvantages of using BEM methodology -

  • Long CSS class names, which might make your HTML markup look messy.

  • Steep learning curve


💡 Bonus - BEM in SCSS

Below is the rewrite of our example CSS code in SCSS -

nav {
  width: 100%;
  height: 5rem;
  background: teal;

  .nav {
    height: 100%;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-around;

    @at-root #{&}__nav-item {
      font-size: 1.5rem;
      text-decoration: normal;

      @at-root #{&}--active {
        text-decoration: underline;
        font-weight: bold;
      }
    }
  }
}

Above SCSS code will generate nav, nav__nav-item & nav__nav-item--active CSS classes after compilation by Sass compiler.


I hope this blog helped you to understand & quickly get started with BEM methodology in CSS. You can learn more at BEM.info, getbem.com

Did you find this article valuable?

Support Arjun Reddy by becoming a sponsor. Any amount is appreciated!