DEV Community

Victor Nwanguma 👨‍🚀
Victor Nwanguma 👨‍🚀

Posted on

BEM and SASS "The Cake and Icing"

What is BEM

BEM stands for (Block-Element-Modifier) is a naming methodology, which aims to solve many of the problems you’ll commonly encounter when naming classes and structuring your CSS.

What is SASS

Sass is a stylesheet language that’s compiled to CSS. It allows you to use variables, nested rules, mixins, functions, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized and makes it easy to share design within and across projects. It is truly "CSS with superpowers"

Block

Standalone entity that is meaningful on its own.
Below are examples of block classes:

/* example 1 */
.button {
  ...
}

/* example 2 */
.nav {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Element

A part of a block that has no standalone meaning and is semantically tied to its block. It is a combination of its block name and element name.
Below are examples of block-element classes:

/* example 1 */
.button__primary {
  ...
}

/* example 2 */
.nav__item {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Modifier

A class on a block or element. Used to change appearance or behavior.

/* example 1 */
.button--disabled {
  ...
}

/* example 2 */
.nav--active {
  ...
}
Enter fullscreen mode Exit fullscreen mode

Conventional example

<nav class="nav">
  <ul class="nav-list">
    <li class="item">
      <a class="link"></a>
    </li>
    <li class="item active">
      <a class="link"></a>
    </li>
  </ul>
</nav>
Enter fullscreen mode Exit fullscreen mode

BEM example

<nav class="nav">
  <ul class="nav__menu">
    <li class="nav__item">
      <a class="nav__link"></a>
    </li>
    <li class="nav__item nav--active">
      <a class="nav__link"></a>
    </li>
  </ul>
</nav>
Enter fullscreen mode Exit fullscreen mode

BEM and SASS combination

This is where "BEM becomes the cake and SASS the icing". One of the small but incredibly powerful features you get in SASS, is the ability to nest your class selectors.

.nav {
  ...

  &__menu {
    ...
  }

  &__item {
    ...
  }

  &__link {
    ...
  }

  &--active {
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

The & essentially saves us rewriting the parent selector over and over. What we end up with is the styles for our nav component encapsulated into a single block. Having the classes in one block like this makes it easy to identify, edit and move around.


Tips when using BEM & SASS (important !)

  • Structure and Naming:
    BEM has some inherit problems, like everything that you style needs to have a class, and BEM don't allow cascading (if you follow the rules strict).

  • BEM Grandchildren - Handling Deeply Nested Elements:
    Chaining Elements Together - The Typical Grandchild Mistake

<div class=“nav”>
    <ul class=“nav__menu”>
        <li class=“nav__menu__item”>
            <a class=“nav__menu__item__link”>Home</a>
        </li> 
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

It makes your class names difficult to read, and it bloats your HTML and CSS files needlessly.

This method also sticks to the DOM structure, limiting your flexibility if the structure of your HTML changes.

Vladimir Grinenko is on the Yandex team (the creators of the BEM methodology) and said this:

BEM methodology doesn’t recommend to use elements within elements in class names. You don’t need to resemble DOM structure in naming. Having one level structure makes refactoring much easier.

— Vladimir Grinenko, Yandex

The deeply nested solution
Instead of chaining elements like nav__menu__item__link, simply focus on the block name itself and use that as the main anchor:

<div class=“nav”>
    <ul class=“nav__menu”>
        <li class=“nav__item”>
            <a class=“nav__link”>Home</a>
        </li> 
    </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

Taking this approach also makes your code much more readable for other developers, as they can easily see all the elements that have a relationship with the block (in this case: .nav).

And if you need to add or remove HTML elements in the future, no refactoring is required.


Further reading


Refrences

Discussion (0)