9 minutes read

Organizing your code isn't usually a problem when building smaller apps or websites. Creating the necessary files based on the components you need and separating the components in a logical way is normally sufficient. But the same isn't true for bigger projects or websites. If you have loads of lines of code, especially in CSS, organizing everything can become difficult. Structuring your CSS code well and using sensible naming conventions is particularly crucial when working in a team — you need an approach that everyone understands and follows consistently. That's where BEM can help. Read on to learn about this methodology and see some examples of how it can be used.

What is BEM?

BEM stands for Block, Element, and Modifier. It's a CSS naming convention that's highly useful and makes your front-end code easier to understand. It's widely used in the industry and can help you write modular CSS code. BEM only relies on CSS class names to apply styles to your HTML code, so there are no HMTL tag or ID selectors. BEM class names consist of up to three parts: block__element--modifier. You can see how BEM classes are written below:

.block { ... }

.block__element { ... }

.block--modifier { ... }

.block__element--modifier { ... }

Block

Blocks represent objects or containers in your webpage. They typically contain bigger chunks of code and can be reduced into smaller parts based on components. The most common blocks in a website are headers, content, cards, footers, and so on. The way to name blocks in CSS according to the BEM convention is shown below:

.block { ... } /* Blocks are named as standard CSS classes */

.content { ... }

.header { ... }

Block names are usually a single word like .content. But if you want to use longer names, the words must be separated by a hyphen -.

Element

An element is a component in a block that provides some information or performs a particular function. This element must be defined in the context of the block. Blocks contain various element types. Some examples of elements include articles inside a content block, items within a navbar, and input fields inside a search block.

The naming of an element must start with its parent block name. This is followed by two underscores (__) and the element's name. The following code snippet demonstrates how elements are named:

.content__article { ... } /* block__element */

.search__input { ... }

.navbar__items { ... }

An element can only have one parent block and can't be used outside its parent block.

Modifier

Modifiers represent different styles or states of classes — they can be used with blocks and elements. The naming of a modifier must start with its parent block/element name. This is followed by two dashes (--) and the modifier's name.

The below examples illustrate how to implement modifiers in CSS code:

.form { ... } /* block */

.form--large { ... } /* block--modifier */

.form--small { .. } 

.form__button--green { ... } /* block__element--modifier */

.form__button--red { ... }

You can only use a modifier with a parent block/element.

BEM examples

Next, we'll look at an example of a card from the JetBrains website and replicate the code following the BEM methodology. Later in this section, you'll see how you can apply BEM in your projects.

The blue snippet card with content


You can see the card's components broken down using the BEM methodology below:

Selected elements on a blue card

In our example, the parent block will be the outer block/container — we'll give it the name card in our HTML code. The card's logo and title, "Space," will be defined as an element. And the information below the title will be treated as a separate element. Depending on team requirements, the card's button can be defined as a block or an element. If a website has several similar cards, treating the button as a block will enable it to be reused. But if there's only one card of this type, it makes sense for the button to be considered an element, which is what we'll do in this example.

Following BEM conventions, the CSS code can be written as follows:

.card { ... } /* block */

.card__title { ... } /* block__element */

.card__info { ... }

.card__button { ... }

/* Alternatively, a modifier could be used to apply a style to the button */

.card__button--green { ... } /* block__element--modifier */

Now let's look at some examples of CSS code written following the BEM methodology:

  • A block component with no element or modifiers.

<style> 
    .button { ... } 
</style> 

<button class="button"></button> 
  • A block component with a modifier.

/* This is the correct way */
<button class="button button--primary"></button>

<style> 
    .button { ... }

    .button--primary { ... }
</style>




/* Don't do it this way */
<button class="button--primary"></button>

<style> 
    .button--primary { ... }
</style>

As shown above, you must include the block and modifier classes when following the BEM naming convention.

  • A block component with elements.

/* This is the correct way */
<section class="card">
    <img class="card__logo" src="photo.png">
    <p class="card__info"> Card Information</p>
</section>

<style>
    .card { ... }

    .card__title { ... }
 
    .card__info { ... }
</style>


/* Don't do it this way */
<section class="card">
    <img src="photo.png">
    <p> Card Information</p>
</section>

<style>
    .card { ... }

    .card img { ... }
 
    .card p { ... }
</style>

It's important to remember that one of the main objectives when using BEM is to keep the specificity low and consistent. BEM uses a single class name for most selectors, reducing the risk of future cascade issues.

Also, keep in mind that using BEM is not the only option. Some developers consider writing pure CSS a cleaner approach. But if BEM is being used in a project, it's vital that all team members follow it when naming classes.

Conclusion

In this topic, you learned about the BEM methodology and how you can use it to write structured code. Its class names are intended to be intuitive, making it easy for the whole team to understand the purpose of a website's elements. Remember that BEM eliminates CSS selectors, and every HTML element has its own class.

51 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo