blueSheep[dev];
Use Sass extend with BEM
Written on Oct 21, 2022 by Remco Kersten in Frontend
If you often use the BEM architecture, you will probably have encountered this: you added the modifier class to an element, but forgot to add the element class. Your layout isn’t working as expected, and you’re wasting time figuring out what’s going wrong.
For this reason, some developers prefer to only add the modifier class in the HTML code, instead of adding both te element- and modifierclass. In this blog post I will show you how to achieve this with the extend rule in Sass.
Omitting the elementclass is not according to the official BEM rules. But rules can be broken.
BEM stands for Block Element Modify. The goal of BEM is to make the structure of CSS clear, more maintainable and reusable.
According to BEM, your web page is made up of blocks with elements in it:
The associated HTML and CSS code according to the BEM method looks like this: Note here that the elements have two classes, namely the element class and a modifier class. After all, this is according to the BEM method.
<div class="menu">
<div class="menu__item">Home</div>
<div class="menu__item menu__item--purple">About me</div>
<div class="menu__item">Projects</div>
<div class="menu__item menu__item--green">Contact</div>
</div>
.menu {
display: flex;
justify-content: center;
gap: 30px;
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-weight: 100;
}
.menu__item {
padding: 5px 15px;
border-radius: 5px;
color: #ffffff;
background-color: #2c3e50;
}
.menu__item--purple {
background-color: #8e44ad;
}
.menu__item--blue {
background-color: #2980b9;
}
.menu__item--green {
background-color: #16a085;
}
Since this article is about sass I will show you what the sass code currently looks like and how the above CSS is generated:
$colors: (
"purple": #8e44ad,
"blue": #2980b9,
"green": #16a085,
);
.menu {
display: flex;
justify-content: center;
gap: 30px;
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-weight: 100;
&__item {
padding: 5px 15px;
border-radius: 5px;
color: #ffffff;
background-color: #2c3e50;
@each $name, $value in $colors {
&--#{$name} {
background-color: $value;
}
}
}
}
.menu
is the class for the menu (block).menu__item
is the class for the menu buttons (elements)So far a short recap about BEM with an example project. What if we add a modifier class, can we omit the element class? So as follows:
<div class="menu__item--purple">About me</div>
The answer is: no!
The class menu__item--purple
contains only the color. The other style properties are in menu__item
. So we have to add both the element class and the modifier class following the BEM method:
<div class="menu__item menu__item--purple">About me</div>
However, since we can actually recognize from menu__item--purple
that this is a menu__item
, it might make sense to omit the elementclass.
Suppose you choose to omit the element class if a modifier class is present. How do you make sure that the modifier class still takes over the rules of the element class?
In the above sass file, a modifier class is created for each color. By now indicating that this is an extension of menu__item
, a selector is added for the relevant modifier class.
$colors: (
"purple": #8e44ad,
"blue": #2980b9,
"green": #16a085,
);
.menu {
display: flex;
justify-content: center;
gap: 30px;
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-weight: 100;
&__item {
padding: 5px 15px;
border-radius: 5px;
color: #ffffff;
background-color: #2c3e50;
@each $name, $value in $colors {
&--#{$name} {
@extend .menu__item;
background-color: $value;
}
}
}
}
Where previously the style of a button was only applied to elements with the class menu__item
, they are now also applied to elements that have a modifier class:
.menu {
display: flex;
justify-content: center;
gap: 30px;
font-family: "Gill Sans", "Gill Sans MT", Calibri, "Trebuchet MS", sans-serif;
font-weight: 100;
}
.menu__item,
.menu__item--green,
.menu__item--blue,
.menu__item--purple {
padding: 5px 15px;
border-radius: 5px;
color: #ffffff;
background-color: #2c3e50;
}
.menu__item--purple {
background-color: #8e44ad;
}
.menu__item--blue {
background-color: #2980b9;
}
.menu__item--green {
background-color: #16a085;
}
Because of this, if an element has a modifier class, we can now remove the element class:
<div class="menu">
<div class="menu__item">Home</div>
<div class="menu__item--purple">About me</div>
<div class="menu__item">Projects</div>
<div class="menu__item--green">Contact</div>
</div>