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*/
}
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;
}
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;
}
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>
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>
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;
}
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>
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 */
}
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>
In the example above:
- Line 1 contains a block named
.content
assigned to its parent elementdiv
. - 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>
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>
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>
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>
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 */
}
Or
.block-name_modifier-name {
/*write your CSS Styles */
}
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>
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
andbold
. Remember that we gave themred
andblack
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: