DEV Community

Cess for Hackmamba

Posted on • Edited on • Originally published at hackmamba.io

How BEM works in building large applications with custom CSS.

This post was originally published on Hackmamba

With the advancement of web applications, there is the requirement to build even more complex interfaces. These applications are likely to have several custom CSS classes. As a result, making the CSS class names readable and understandable becomes paramount. The block, element, and modifier (BEM) approach assist us in this situation.

We'll examine the BEM methodology and how we use it to build large applications with custom CSS.

Prerequisite

We'll need a basic understanding of HTML and CSS to follow this article.

The BEM Methodology

Yandex, a Russian IT company, invented BEM in 2005. The main goal of BEM is to help us maintain the structure, readability, and flexibility of our CSS.

BEM stands for Block, Element, and Modifier. BEM divides CSS classes into independent modules, making collaboration with developers easier.

Example of the BEM Syntax:

.block__element_modifier {
    /* write your CSS styles*/
}
Enter fullscreen mode Exit fullscreen mode

If we look at a random piece of source code online and see a class name like .btn__text_bold, that's BEM. The code .btn__text_bold is easy to understand even if we have no prior knowledge of CSS. That is the beauty of BEM.

BEM works only with CSS classes, not IDs or tag selectors. CSS classes enable us to reuse class names many times in a style sheet.

What are the advantages of working with BEM?

There are many advantages to using BEM. Here is a few of them:

  • Reusability: Due to BEM's reusability, we'll have fewer lines of code to maintain. BEM makes it possible to write code that is both flexible and manageable. BEM reusability increases teamwork and productivity among developers.
  • There are fewer CSS conflicts.
  • Structure: Our code will be more organized with BEM, making it easier to read and understand.

BEM - The letter B represents a Block.

Blocks are significant elements that can stand on their own, and we can also reuse them on other parts of the CSS. Class attributes represent blocks in HTML. We assign block names to parent elements.

Some of the most common blocks found on websites are:

  • The header.
  • The content.
  • The sidebar.
  • The footer.
  • The search engine.

Remember we defined Blocks as significant elements that can stand on their own? How does that work?

.btn {
    font-size: 2em;
    color: red;
    text-shadow: 1px 3px 1px black;
} 
Enter fullscreen mode Exit fullscreen mode

The block name answers the question, "what is it for?". It's clear from the block name .btn that the developer is styling the button element. The block name .btn is easy to read and understand.

In the block name, we can find answers to questions like:

  • "What is he up to?" - He's applying a style to the input element.
  • "What is the purpose of it, then?." - To style the input element.
 .input {
      font-size: 2em;
      color: red;
 }
Enter fullscreen mode Exit fullscreen mode

In the example above, we can see that the developer is styling the input element. The block name gives a clear picture of what the developer is doing.

The block name explains what the block does. It does not tell us what the block looks like, i.e., its appearance.

Here's an example to explain the above statement:

Don't do this:

 /*wrong Practice*/
    <div class="green-content">
       <h2>CSS Is Fun</h2>
    </div>
Enter fullscreen mode Exit fullscreen mode

The above example contains the class name .green-content.

.green-content describes the appearance. It does not tell us the purpose of the block name.

Do this instead:

 /*Best Practice*/
    <div class="content">
       <h2>CSS Is Fun</h2>
    </div>
Enter fullscreen mode Exit fullscreen mode

The above example contains a class name .content that is meaningful on its own. An external developer would not find it difficult to understand the code if they looked at it.

How can I create a block name that contains more than one word?

The majority of block names consist of a single word, such as:

  • .input
  • .header
  • .btn
  • .content
  • .menu

In cases where we have longer block names, we divide each word with a single hyphen -.

Example:

  • .btn-text
  • .btn-color
  • .menu-text

Practical example:

.btn-color {
      font-size: 2em;
      color: red;
      text-shadow: 1px 3px 1px black;
}
Enter fullscreen mode Exit fullscreen mode

How can I nest block names within each other?

The term "nest" refers to the placement of one element inside another. So, when we say "nest block names," we refer to putting one block name inside another.

Here is an example of how to nest block names:

    <header class="header">
       <img src="#" alt="#">  
       <nav class="navbar"> 
          /* Write your HTML elements */
       </nav>
    </header>
Enter fullscreen mode Exit fullscreen mode

In the example above, the block named .header has another block called .navbar nested inside it.

BEM - The letter E represents an Element.

An element is always a part of a block name. It cannot exist by itself. On its own, it has no meaning unless we place it alongside a block name. We assign element names to child elements.

The element name begins with a double underscore __.

The syntax for element names:

 .block-name__element-name {
    /*write your CSS Styles */
 }
Enter fullscreen mode Exit fullscreen mode

Like the block name, the element name answers the question "what is it for?" and gives us a clear picture of the developer's code.

Here are some examples of element names:

  • .content__text
  • .header__img
  • .list__item

A practical example of element names using .content as the block name:

    <div class="content">
       <h2 class="content__title">Always Code</h2>
       <img class="content__img" src="#" alt="#">
       <p class=""content__description">coding everyday yields 
       results</p>
    </div>
Enter fullscreen mode Exit fullscreen mode

In the example above:

  • Line 1 contains a block named .content assigned to its parent element div.
  • Lines 2, 3, and 4 are the div children, the parent element.
  • line 2, 3 and 4 all have element names .content__title, .content__img, and .content__description. The element names are straightforward, so it's easy to know what the developer is working on.

Like the block name, the element name describes what the element does. It does not tell us what it looks like, i.e., its appearance.

Here's an example to explain the above statement:

Don't do this:

 /*wrong Practice*/
    <div class="content">
       <h2 class="content__bold">CSS Is Fun</h2>
    </div>
Enter fullscreen mode Exit fullscreen mode

The above example in line 2 contains the class name .content__bold. It describes the appearance. It does not tell us the purpose of the element name.

Do this instead:

  /*Best Practice*/
     <div class="content">
       <h2 class="content__title">CSS Is Fun</h2>
     </div>
Enter fullscreen mode Exit fullscreen mode

The above example in line 2 contains a class name .content__title that is meaningful on its own. An external developer would not find it difficult to understand that line of code if they looked at it.

How can I nest element names within each other?

We've already discussed the definition of nesting. We should be familiar with it by now. As a quick reminder, the term "nest" refers to the placement of one element inside another. So, when we say "nest element names," we refer to putting one element name inside another.

It is vital to use the pattern .block-name__element-name when nesting element names.

Here is an example of how to nest element names:

Don't do this:

    <main class="main-content">     
      <div class="main-content__wrapper">         
         <h2 class="main-content__wrapper__title">Coding is 
         fun</h2>         
         <p  class="main-content__wrapper__description">Remember 
         to code today</p>     
      </div>
    </main>
Enter fullscreen mode Exit fullscreen mode

The above example does not follow the .block-name__element-name pattern. Our element names will become difficult to read if we nest them in this manner.

Do this instead:

  <main class="main-content">
        <div class="main-content__wrapper">
            <h2 class="main-content__title">Coding is fun</h2>
            <p  class="main-content__description">Remember to code 
            today</p>
        </div>
  </main>
Enter fullscreen mode Exit fullscreen mode

The above example follows the .block-name__element-name pattern. Nesting our element names in this manner makes it easy to read. An outside developer would not find it challenging to understand the code if they looked at it.

BEM - The letter M represents a Modifier.

Both the element and block names describe what it does, but that's not the case for modifiers. Modifiers tell us what the element or block looks like, i.e., its appearance, size, or behavior.

The modifier name begins with a single underscore _.

The syntax for modifier names:

 .block-name__element-name_modifier-name {
    /*write your CSS Styles */
 }
Enter fullscreen mode Exit fullscreen mode

Or

 .block-name_modifier-name {
    /*write your CSS Styles */
 }
Enter fullscreen mode Exit fullscreen mode

Modifiers cannot stand alone. We use them with the block and element names.

It's up to us to decide whether to add modifiers to our block and element names. It's not compulsory to use them.

Disabled, green, and bold are some examples of modifier names.

The modifier is helpful if we want to change the styles of HTML elements with similar block names.

Here's an example to explain the above statement:

    <button class="btn-text">
      sign up
    </button>

    <button class="btn-text btn-text_red">
      sign up 
    </button>

    <button class="btn-text btn-text_bold">
       sign up         
    </button>
Enter fullscreen mode Exit fullscreen mode

In the above code:

  • We have 3 HTML button elements with the same block name .btn-text.
  • We gave two-button HTML elements, the modifier names red and bold. Remember that we gave them red and black modifier names to distinguish them from one another.

I hope we understand how the Modifier name works?.

To learn more about how the modifier works, see the articles in the resource section.

CONCLUSION

This article has taught us how to use BEM with custom CSS to build a solid foundation for our projects.

There are other approaches to web development, but none have proven to be as effective as the BEM process. The BEM methodology enables us to write more organized and readable codes. We can collaborate with other developers in the future if our code is clean and organized.

Resources

Here are some resources we may find helpful:

Top comments (2)

Collapse
 
thomasbnt profile image
Thomas Bnt

Cool post about BEM. Don't hesitate to put your code with the good rule like :

.css_tag {
   color: red;
}
Enter fullscreen mode Exit fullscreen mode

Preview Code CSS Markdown

Collapse
 
fazy221 profile image
Faizan Raza

Great explanation I must say! Two things I would like to change are:

  • For modifiers, I believe -- is preferred instead of _. I'm seeing someone using _ first time for modifiers.
  • For deeply nested element like 2nd children, you said it's more preferred to use __ from first parent block instead of the child's direct parent. What if first children element of a block has two childrens A and B. Both will be using their grandparent's block in their name which could confuse a developer.