BEM - An Overview
Tags: bem, css, frontend
Published: 2021-01-21 18:17:37

Good day reader and welcome to my post. Today, I will talk about a CSS naming convention that has definitely been around for quite long --- **BEM**.

On smaller sites, how you organize your styles or write your CSS, name your classes isn’t really a big deal. You may decide to call your classes whatever names you deem wish, give whatsoever name you want to classes, etc.

Take for instance, we may decide to give our classes whatsoever name like this:

**CSS**
  ```
  .person-container .person {
    display: block;
    ...
  }

  .right-handed-person {
    float: right;
    ...
  }

  .left-handed-person {
    float: left;
    ...
  }
  ```

However, when our application gets really large and complex, this would lead to unmaintainable code, difficult for others to maintain. So, for larger, more complex projects, how you organize your code is really important to increase efficiency in that:

   - It affects productivity; *how you write your code determines how long it takes you to write it*,
   - It affects maintainability; *how you write your code determine how effectively others can be able to contribute to your codebase*
   - It affects performance; *how you write your code determines if browsers would load it fast or slow*

So, for these and more, I have come to talk to you about a naming methodology for CSS I began using. Note that there are plenty of them out there with similar goals such as organizing cooperation among programmers, increasing productivity, enhancing maintainability.
Those methodologies are:
  - [SUITCSS](http://suitcss.github.io/) : Structured class names and meaningful hyphens
  - [SMACSS](http://smacss.com/) : Style-guide to write your CSS with five categories for CSS rules
  - [OOCSS](http://oocss.org/) : Separating container and content with CSS “objects”

Now, let's talk about BEM

# BEM Introduction
> [BEM](http://getbem.com/) is a design methodology that helps you to create reusable components and code sharing in front-end development. — Getbem.com

[**BEM**](https://en.bem.info/method) stands for **B**lock **E**lement **M**odifier. It is a method of naming CSS and HTML classes developed by the guys at [Yandex]( https://en.bem.info/).
The aim of BEM is to help developers better understand the relationship that exist between HTML and CSS in a given project.

## Block

The `B` in **BEM** stands for `Block` and by this, it means any entity which exists on its own and still makes sense to you using it (meaningful); talking from the perspective of HTML. Blocks can be nested and interact with each other, but semantically, they remain equal; there is no precedence or hierarchy.

 Examples:
`header`, `navbar`, `input`, `container`, `sidebar`, `footer`
You see, these can exist on their own and make sense, they are the parent of other subsequent *elements* that come after them.

You might be wondering if these could standalone and make sense, what wouldn't. Well, if you have this thought, below are what wouldn't make sense as a block:
`header title`, `nav items`, `label for an input` ,  etc.

Take for instance, we may have:

**CSS**
```
.person-container {
  display: block;
  ...
}
```

### Rule using Block
  - While **naming**, block names may include Latin letters, digits, and dashes; example: `.person-container`
  - In the HTML, any [DOM node](https://developer.mozilla.org/en-US/docs/Web/API/Node) can be a block if it accepts a class name. example `<div class="person-container">...</div>`
  - In the CSS, you must:
    - Use class name selector only; *do* `.person-container`
    - Not use tag name or ids; *do not do* `.person-container #person`
    - Not use dependency on other blocks; *do not do* `.person-container .person`


## Element

The `E` in **BEM** stands for `Element` and by this, it is that/those part/s of a block that has no meaning on its/their own, that is if it/they exist/s outside a `block`, it makes no sense, that means it is semantically tied to its block.
  Examples:
`header title`, `list item`, `menu items`, `input label`
Let's take a look at our code:

**CSS**
```
.person-container {
  display: block;
  ...
}

.person-container__left-handed-person {
  float: left;
  ...
}

.person-container__right-handed-person {
  float: right;
  ...
}
```

### Rule using Element
  - While **naming**, element names may include Latin letters, digits, dashes, and underscore. The CSS class is formed as the *block name* plus *two underscores* plus *element name*. Example: `.person-container__left-handed-person`

  - In the HTML, any [DOM node](https://developer.mozilla.org/en-US/docs/Web/API/Node) within a block can be an element. Within a given block, all elements are semantically equal.
  Example:

**HTML**
```
<div class="person-container">
  <span class="person-container__left-handed-person">...</span>
  <span class="person-container__right-handed-person">...</span>
  ...
</div>
```
  - In the CSS, you must:
    - Use class name selector only; *do* `.person-container__left-handed-person`
    - Not use tag name or ids; *do not do* `.person-container__left-handed-person #left-handed-person`
    - Not use dependency on other blocks; *do not do* `.person-container__left-handed-person .left-handed-person`

## Modifier

The `M` in **BEM** stands for `Modifier`. It is a flag that is used to modify how a block behaves or appears. These modifiers can generally be anything that can modify the block.
  Examples:
`tall`, `short`, `small`, `disabled`, `success`, `failure`, `alert`, `red`
Let's take a look at our code:

**CSS**
```
.person-container {
  display: block;
  ...
}

.person-container__left-handed-person {
  float: left;
  ...
}

.person-container__right-handed-person {
  float: right;
  ...
}

.person-container--tall {
  height: 500px;
  ...
}

.person-container--short {
    height: 200px;
  ...
}
```

### Rule using Modifier
  - While **naming**, modifier names may include Latin letters, digits, dashes, and underscore. The CSS class is formed as the *block name* or *element name* plus *two dashes*. Example: `.person-container--tall` or `.person-container--short`.

  - In the HTML, a modifier is always an extra class name which you add to a block or an element [DOM node](https://developer.mozilla.org/en-US/docs/Web/API/Node). As stated above, modifiers are used to modify either a block or an element and such should only be added to blocks or elements they modify and keep the original class.
  Example:

**HTML**
  ```
  <div class="person-container person-container--tall">
    <span class="person-container__left-handed-person">...</span>
    <span class="person-container__right-handed-person">...</span>
    ...
  </div>
  
  <div class="person-container person-container--short">
    <span class="person-container__left-handed-person">...</span>
    <span class="person-container__right-handed-person">...</span>
    ...
  </div>
  ```

  - In the CSS:
    - Use modifier class name as selector; example: `.person-container person-container--short`


# Usefulness of BEM

Yo, I'm glad you still reading up to this point. I just want to highlight few points. I mentioned earlier that there are many methodologies out there which aim to organize cooperation among developers and maintain large CSS codebase.

BEM provides:
  - **Independence**: Each block in BEM is never dependent on another block, you will never have to worry about [problems from cascading](http://www.phase2technology.com/blog/used-and-abused-css-inheritance-and-our-misuse-of-the-cascade/).
  - **Reusability**: Because your blocks are independent of each other, you can re-use each block multiple times; and thus reduces the number of CSS codes you will have to write which invariably increases productivity.
  - **Solid CSS Structure**: Using BEM methodology gives your CSS a solid structure which will remain easy to understand.
  - **Increase Cooperability**: When you use BEM methodology as a team, everyone in the team would definitely understand what each CSS class written does, thus preventing [problems from cascading](http://www.phase2technology.com/blog/used-and-abused-css-inheritance-and-our-misuse-of-the-cascade/).

For me, besides the points outlined above, I chose BEM because it was my first love over other methodologies, I found it direct, less confusing (don't want to say not confusing :-D). For others, it may be different, whichever it is, I will love to know why you choose to use it.

# Summary

I will like to say that BEM doesn't solve 100% of all the problems frontend web developers encounter, but it sure helps us agree on a term in order to build that extraordinary maintainable user interfaces we hope will adapt over time.
Thanks for reading. You can catch me on Twitter [@eunit99](https://twitter.com/eunit99)

## Further Readings:
1 - [BEM - Block Element Modifier](http://getbem.com/introduction/)
2 - [The BEM project website](https://en.bem.info/)
3 - [A quick introduction to Block Element Modifiers (BEM)](https://www.freecodecamp.org/news/a-quick-introduction-to-block-element-modifiers-bem-9df46d29b64c/amp/)
4 - [BEM like naming](http://cssguidelin.es/#bem-like-naming)
5 - [Building a modular My Health Skills with BEM and Sass](http://www.bluegg.co.uk/building-my-health-skills-part-3/)
6 - [BEM It! for Brandwatch](http://www.slideshare.net/MaxShirshin/bem-it-for-brandwatch)