About the author
@catalinmpit is a software engineer, AWS community builder and technical writer based out of London. He’s currently an engineer at TypingDNA, working on applying keystroke dynamics as a means of biometrics authentication.
Check out more of his work on catalins.tech
Should you use BEM + SASS? It depends.
“It depends?" Well, yes! In many cases, it comes down to personal preference. It’s up to you to decide whether you choose to use this combination in your projects or not. Throughout this article, we are going to investigate what they are, how they work, and the benefits of using them.
First of all, let’s dive into what BEM & SASS are.
What’s BEM?
BEM (Block Element Modifier) is a commonly used naming convention for writing classes in HTML. It helps you speed up the development process while keeping things organized and easy to understand for the whole team.
It is based on a simple idea where every big chunk of markup is called a Block. Everything inside a block is called an Element. And the Modifiers are variants of a specific block or element.
Let’s take a look over the following example for a better understanding:
<section class="bar">
<img class="bar__logo" src="#"/>
<ul class="bar__list">
<li class="bar__item">
<a href="#" class="link link--highlight">Item 1</a>
</li>
<li class="bar__item">
<a href="#" class="link">Item 2</a>
</li>
<li class="bar__item">
<a href="#" class="link">Item 3</a>
</li>
</ul>
</section>
Here we have a block called "bar"
. It contains an image “bar__logo”
and a list “bar__list”
of links
“bar__item”
and “link”
(which is another small block used throughout the project). For one of the links, we also
have a modifier, "--highlight"
, which points out that our link will look different from the others. That’s it!
The same approach can be applied to any other type of block. For more details regarding BEM, check out the documentation.
What’s SASS?
SASS (Syntactically Awesome Style Sheets) on the other hand, is a CSS preprocessor that makes writing style syntax much faster and easier to read.
“Prepro-what?" Think of CSS Preprocessors as programs that help you generate CSS using a unique syntax. Things like operators, nesting, mixins, inheritance (which are available in SASS) that are easier to write and maintain.
For examples in this article, we’ll use SCSS which is a variation of SASS, and more closely resembles CSS syntax. You can find the basics as well as the syntax difference between SASS & SCSS here. Here’s a simple example:
//variables
$color-red: #FF0000;
$color-gray: #CCCCCC;
$color-black: #111111;
$spacing: 5px;
//nesting
.bar {
border: 1px solid $color-gray; // variable use
&__list {
padding: 0 3 * $spacing; //operation including variable
}
&__item {
list-style: none;
background-color: $color-black;
margin-bottom: $spacing;
padding: 2 * $spacing;
}
&__logo {
display: none;
}
}
.link {
text-decoration: none;
color: $color-red;
&--highlight {
font-weight: bold;
}
}
It’s pretty straight forward. Notice how we’re already combining it with BEM.
The Wild Wild West
Now that we’ve covered BEM & SASS, let’s learn more by studying a common mistake in a real-world example. One might be tempted to write:
<section class="profile-card">
<p class="profile-card__name">Name<p>
<div class="profile-card__actions">
<button class="profile-card__actions__save">
<span class="profile-card__actions__save__icon" />
<p class="profile__card__actions__save__text">Save</p>
</button>
<button class="profile-card__actions__delete">
<span class="profile-card__actions__delete__icon" />
<p class="profile__card__actions__delete__text">Delete</p>
</button>
</div>
<div class="profile-card__info">
Lorem ipsum
<button class="profile-card__info__button">
Request info
</button>
</div>
</section>
The SCSS will perfectly nest:
.profile-card {
&__name {
font-size: 14px;
}
&__actions {
padding: 10px;
&__save,
&__delete {
&__icon,
&__text {
color: white;
@debug &;
}
&__text {
font-size: 12px;
}
}
&__save {
background: black;
}
&__delete {
background: red;
}
}
&__info {
&__button {
color: white;
background: black;
}
}
}
However, there’s an issue with this approach; it’s not following the BEM naming methodology. Writing such nested classes for the elements within blocks should be avoided. Why? Because it will result in some long class names, such as:
.profile__card__actions__delete__text
You may think: “Then I’ll skip the class and target tags directly”. That’s doesn’t adhere to the BEM methodology either. The preferred way to go about this is:
<section class="profile-card">
<p class="profile-card__name">Name</p>
<div class="profile-card__actions">
<button class="btn btn--black">
<span class="btn-icon btn-icon--check"/>
<p class="btn-text">Save</p>
</button>
<button class="btn btn--red">
<span class="btn-icon btn-icon--trash"/>
<p class="btn-text">Delete</p>
</button>
</div>
<div class="profile-card__info">
Lorem ipsum
<button class="btn btn--black">Request info</button>
</div>
</section>
Where your styling will look like this:
.profile-card {
&__name {
font-size: 14px;
}
&__actions {
padding: 10px;
}
}
.btn {
&--red,
&--black {
color: white;
}
&--red {
background: red;
}
&--black {
background: black;
}
&-icon,
&-text {
color: white;
}
&-text {
font-size: 12px;
}
}
It looks a lot better, right? By doing this, you’ll avoid long class names. Having small blocks also makes it easy to reuse, so you’ll save time when making updates later. Also, it makes it easier to maintain the look of basic elements which are shown across all of your project (e.g. buttons, links).
One Last Trick
There are times when refactoring the markup is not an option (e.g. large project with altered BEM syntax), so let’s return to the original example. If you’re in a situation like this and you find it hard to target given elements from SCSS, try debugging.
“You can debug SASS?" That’s right. You can debug and output your compiled nested styling using @debug
.
...
&__save,
&__delete {
&__icon,
&__text {
color: white;
@debug &;
}
}
...
The output will be:
.profile-card__actions__save__icon, .profile-card__actions__save__text, .profile-card__actions__delete__icon, .profile-card__actions__delete__text
Debugging makes it easy to spot syntax mistakes and fix them.
Conclusion
As mentioned, this way of working may or may not be the right fit for you. Feel free to give it a go and see if it is. You can even adapt it to your style, but make sure you remain consistent with the methodology you use/modify.
Happy coding.
Catalin regularly posts helpful development tips and guides on Twitter. Be sure to follow him at @catalinmpit