BEM: A CSS Naming Methodology for Clear and Organized Code

Justine Peterson Mahinyila
ClickPesa Engineering Blog
6 min readMay 14, 2023
Photo by Farzad on Unsplash

I once heard that “there are only two hard things in computer science: cache invalidation and naming things.” The second part of this statement has always been actual every time I write CSS.

Over the short period I have been writing code, I have learned that I spend more time reading code than writing. This means I need to understand my code in the future; this was not a thing when I was writing my simple to-do projects until I started contributing to big projects and making software for clients. It was when I started getting lost in my codebases this pushed me to start researching online about better ways to write maintainable future proof CSS code, and concepts like “writing maintainable code,” the BEM methodology in CSS, and many other suitable coding practices methodologies started appearing repeatedly.

I came across BEM by chance and called in love with it. Since then, every time I want to write CSS, I find myself googling and searching about it, and this is what has pushed me to write a simple guide and explainer that I would return to, and of course, anyone new to the concept can find reference through it. You may not need these notes. There are many good notes, but this is your guide if you need something simple and to the point.

By the way, what is this BEM thing that I repeatedly mention? BEM stands for (Block, Element, and Modifier), a CSS naming methodology that assigns each selector to one of three categories: block, Element, or Modifier. This helps define the functionality and relationships between different parts of the code, making it easier to understand and revise in the future.

Now let me break down BEM.

Block

In the context of BEM, a block is a standalone component or section of a webpage, such as a header, container, menu, or button, that can function independently from the rest of the page and be understood even when stripped away from the surrounding website.

A block is part of a webpage that can function independently, is self-contained, and makes sense on its own.

When using the BEM naming methodology, you should name a block based on its function or purpose.

Examples of blocks

1. In a “header” block, which represents the header of the website and can contain the logo and menus

2. In a “menu” block, which can contain the menu items of the website

3. In a “card” block can be a product card in an e-commerce site, which contains the product image, the product name, the price, and a simple description

Element

An element is a part of a block that performs a specific function within that block. It is usually a minor component that cannot function independently and relies on the block it belongs to for context. Examples of elements include a button within a menu block or a paragraph within an article block.

Examples of elements blocks

1. In a “header” block, an “element” could be a “logo.”

2. In a “menu” block, an “element” could be a “menu item.”

3. In a “card” block, an “element” could be an “image.”

4. In a “form” block, an “element” could be an “input field.”

5. In a “slider” block, an “element” could be a “slide.”

Modifiers

In the BEM naming methodology, modifiers are used to change the appearance of a block or Element. They are selectors that produce different versions of blocks and elements, allowing you to change things like size, color, and typography while leaving the rest of the ingredients intact. Modifiers can make certain parts stand out by creating a different version with a unique style. To name a modifier, you first identify what it’s modifying, followed by two dashes, and then the visual type of the Modifier. For example, to modify the font color of a .proj-prev block to mint, you could name the modifier .proj-prev — mint and style it accordingly.

Examples of Block Element Modifiers

1. Block: header, Element: logo, Modifier: dark — .header__logo — dark

2. Block: navigation, Element: link, Modifier: active — .navigation__link — active

3. Block: card, Element: title, Modifier: large — .card__title — large

4. Block: form, Element: input, Modifier: error — .form__input — error

5. Block: button, Element: icon, Modifier: small — .button__icon — small

Class Naming Style

As you might have seen, In the above example, we put double underscores to separate elements from blocks, and double dashes are used to separate modifiers from blocks or elements. This is because it provides a clear and consistent naming structure that helps to avoid confusion and makes the code easier to read and understand.

Using double underscores to separate elements from blocks allows for a clear visual separation between the different levels of the component hierarchy.

Using double dashes to separate modifiers from blocks or elements helps to indicate that the Modifier is a separate entity that modifies the appearance or behavior of the partnership or Element.

One question that I asked myself when I started using BEM was, “How do independent modifier classes that are connected to multiple selectors be reused following the BEM Methodology?”

In BEM, independent classes for modifiers connected to multiple selectors can be reused by simply assigning them to those selectors.

This means you can create a modifier class that changes the appearance of a particular block or Element and then apply that Modifier to multiple blocks or elements throughout your codebase.

For example, let’s say you have a modifier class called “button — small” that reduces the size of a button element. You can then apply this Modifier to any button element that needs to be small by adding the “button — small” class to its existing block and element classes.

By reusing independent modifier classes like this, you can save time and effort in your coding process while still maintaining the modular and organized structure of the BEM methodology.

The other one was Is using a class without connecting it to any block or Element okay?

In BEM methodology, using a class without connecting it to a block or Element is generally not recommended. This is because BEM aims to create a clear and structured naming convention that helps to organize and maintain CSS code. Using unconnected classes can create confusion and make it difficult to understand the purpose of the course. However, in some cases, using standalone methods for specific purposes, such as utility classes that can be used across different blocks or elements, may be acceptable. Following the BEM methodology and using types connected to a partnership or Element is best.

An example of a standalone utility class could define a specific spacing or margin value, such as “.mt-2” for adding a margin-top of 2 units. This class can be applied to any element that requires that specific spacing value, regardless of the block or Element it belongs to. This way, you can avoid repeating the same CSS code for every instance where that spacing value is needed, making your code more efficient and easier to maintain.

Here is an example where the whole BEM methodology is used in a full circle

HTML

<nav class="nav">
<ul>
<li class="nav__link nav__link - active">work</li>
<li class="nav__link"> <a href="/about.html">about</a> </li>
<li class="nav__link"> <a href="/contact.html">contact</a> </li>
</ul>
</nav>

CSS

.nav {
padding-right: 6rem;
text-align: right;
}
.nav__link {
display: inline;
font-size: 3rem;
padding-left: 1.5rem;
}
.nav__link - active {
color: #001534;
}

The above HTML code shows an HTML element with an unordered list containing list items and menu items.

In the CSS code below, we treat the nav element as a block since it has complete functionality and it can stand on its own; hence we assign it to the class nav, then we have the nav items, which in this case are elements, and then we have the modifier class nav__link — active which modifies the color state of the things.

In conclusion, Are you using BEM conversion in naming your classes? Which other methodologies are you using? Which methods are you using for documenting and managing your types? Please let me know in the comments below and let us discuss, Looking forward to hearing from you.

--

--

Justine Peterson Mahinyila
ClickPesa Engineering Blog

My mission is to improve people’s lives and solve problems using technology in Africa