BEM, which stands for Block Element Modifier, is a popular naming convention and methodology for writing maintainable and scalable CSS. It is widely used to create modular and reusable front-end code in large-scale projects. The BEM methodology aims to improve code readability, reduce specificity issues, and make it easier to understand the relationships between different CSS classes.
The BEM methodology follows a specific naming convention for CSS classes:
- Block (B):
- The highest level of abstraction, representing a standalone component or module on the page.
- The block name should be descriptive and represent a distinct part of the interface.
- Element (E):
- Represents a part of the block, and it is always a child of the block.
- The element name is separated from the block name using a double underscore (
__
).
- Modifier (M):
- Represents a variation or state of the block or element.
- The modifier name is separated from the block or element name using a double hyphen (
--
).
The general structure of a BEM class name is as follows:
.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
.block__element--modifier--modifier-value {}
Let’s consider a simple card component as an example:
<div class="card">
<h2 class="card__title">Card Title</h2>
<p class="card__description">This is a card component.</p>
<button class="card__button card__button--primary">Read More</button>
</div>
In this example:
.card
is the block representing the entire card component..card__title
,.card__description
, and.card__button
are elements representing different parts of the card component..card__button--primary
is a modifier applied to the.card__button
element to style it differently when it has a primary action.
There is one more approach in naming which is classic BEM naming convention , instead of two hyphens use single underscore as follows.
.block {}
.block__element {}
.block_modifier {}
.block__element_modifier {}
.block__element_modifier_modifier-value {}
If you need to use two or more words in block , element, or modifier name you can use hyphen to separate words, or you can camelCase (first word lower case and capitalize rest of the words) the words or you can write the words in ReactStyle ( capitalize each words).
.block-name__element-name--modifier-name {}
.blockName__elementName--modifierName {}
.BlockName__ElementName--ModifierName {}
Now lets understand why and how to use BEM , Suppose we have a simple HTML structure for a blog post as below (it’s not using BEM for naming classes):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Document</title>
</head>
<body>
<article class="blog-post">
<h2 class="title">The Importance of BEM</h2>
<div class="content">
<p class="paragraph">BEM is a methodology for writing CSS...</p>
<a href="#" class="button">Read more</a>
</div>
<div class="meta">
<span class="date">Jul 21, 2023</span>
<span class="author">Coding is Simple</span>
</div>
</article>
</body>
</html>
.blog-post {
border: 1px solid #ccc;
padding: 20px;
margin-bottom: 20px;
}
.title {
font-size: 24px;
color: #333;
margin-bottom: 10px;
}
.content {
margin-bottom: 15px;
}
.paragraph {
font-size: 16px;
line-height: 1.6;
color: #666;
}
.button {
display: inline-block;
padding: 8px 15px;
background-color: #007bff;
color: #fff;
text-decoration: none;
border-radius: 4px;
}
.meta {
font-size: 12px;
color: #999;
}
.date {
margin-right: 10px;
}
.author {
font-style: italic;
}
Now, let’s see how applying BEM principles can improve above code:
<article class="blog-post">
<h2 class="blog-post__title">The Importance of BEM</h2>
<div class="blog-post__content">
<p class="blog-post__paragraph">BEM is a methodology for writing CSS...</p>
<a href="#" class="blog-post__button">Read more</a>
</div>
<div class="blog-post__meta">
<span class="blog-post__date">July 21, 2023</span>
<span class="blog-post__author">Coding is Simple</span>
</div>
</article>
.blog-post {
border: 1px solid #ccc;
padding: 20px;
margin-bottom: 20px;
}
.blog-post__title {
font-size: 24px;
color: #333;
margin-bottom: 10px;
}
.blog-post__content {
margin-bottom: 15px;
}
.blog-post__paragraph {
font-size: 16px;
line-height: 1.6;
color: #666;
}
.blog-post__button {
display: inline-block;
padding: 8px 15px;
background-color: #007bff;
color: #fff;
text-decoration: none;
border-radius: 4px;
}
.blog-post__meta {
font-size: 12px;
color: #999;
}
.blog-post__date {
margin-right: 10px;
}
.blog-post__author {
font-style: italic;
}
It instantly improves readability of the code ,CSS classes are more organized which leads to more maintainable, scalable, and reusable code, especially if project becomes large with complex structures and styling requirements.
The code without BEM can become confusing and harder to manage as the project grows, leading to basic class names and time-consuming issues. BEM provides structured naming for clear styles, reducing unexpected results, and ensuring consistency in team projects. It’s not necessary for small projects but becomes essential for larger projects. It makes collaboration easier in larger projects.
Lets take another example of simple button element and apply BEM naming convention to it. Below html element is not using BEM
<button class="button">Click me</button>
In the HTML, we have a block-level element with the class “button.” This is the main container for our button.
.button {
/* Styles for the button block */
background-color: #3498db;
color: #fff;
padding: 10px 20px;
border: none;
}
.button__text {
/* Styles for the button's text element */
font-size: 16px;
}
.button--primary {
/* Modifier class for a primary button */
background-color: #e74c3c;
}
.button--large {
/* Modifier class for a larger button */
padding: 12px 24px;
}
<button class="button button--primary button--large">
<span class="button__text">Click me</span>
</button>
BEM’s way of naming things makes it easy to see how the parts of a web page component connect, helping you understand how HTML and CSS are set up. Elements and modifiers keep the looks and actions of each part separate, which makes organizing code better. This method lets you make different versions of a component without copying CSS code. For example, when you add new modifiers, you change how something looks or add new types of things. BEM keeps naming rules the same, so developers can work together more easily by following the same way of naming CSS classes.
Also read How to apply linear gradient css to elements
How to apply box shadow css to elements