BEM (Block, Element, Modifier) is a great way to keep class naming consistent and meaningful. If you’ve never used BEM before but want to understand how it works, or if you’re thinking about using it for an upcoming site or component, this article is meant for you.
If you’re already familiar with how BEM works, I’m writing another article focused on more use cases and examples. Follow me on Twitter and you’ll know when it’s out.
Intro to BEM
BEM is extremely helpful for building maintainable components that communicate the relationship between elements. Let’s learn by example and build a fake button component first.
B is for Block: This is the name of our main component. In our case, it’s a .button
.
// Our Block!
.button {
padding: .6rem 1.2rem;
color: white;
background: black;
}
E is for Element: This is something that’s dependent upon being inside of the main block and is indicated that it’s an element by using two underscores (__
) to separate it from the main Block name.
// an icon element
.button__icon {
fill: white;
}
// the text of the button
.button__text {
margin-right: 5px;
}
Just from the CSS, if you’re familiar with BEM, you can tell what CSS depends on each other and what the HTML will look like. The .button__text
and .button__icon
elements will both be nested inside the .button
block.
Here’s what our HTML would look like:
<button class="button">
<span class="button__text">Read More</span>
<svg class="button__icon">
<use xlink:href="#icon-chevron--right" />
</svg>
</button>
We have our main .button
block and the elements inside of it (.button__text
and .button__icon
). BEM has given us some structure to see how the CSS is related, as well as how the HTML might be structured. Pretty helpful stuff.
M is for Modifier: What if you want your button to be blue instead of black? No need to build a whole new component! Just add a modifier.
<button class="button button--blue">
...
</button>
// Our Block!
.button {
padding: .6rem 1.2rem;
color: white;
background: black;
}
// our modifier!
.button--blue {
background: blue;
}
Because we’re using BEM naming conventions, we know that .button--blue
depends upon (inherits) the styles from .button
. When we make an edit to .button
, we know it will affect .button--blue
. Conversely, when we make an edit to .button--blue
, we know it won’t affect .button
.
That’s the basics on how to use BEM. Really, that’s it. It’s helpful to use in any size project.
Applying it in an actual site is a whole different beast though. That’s why I’m working on another article about how I’ve used BEM in complex cases to keep it helpful instead of a hinderance.
The BEM Cheatsheet
Here’s a quick cheatsheet of the tips for actually using BEM.
- Formatting:
.block__element--modifier
- Describe the block with a word or two. If it’s two words, separate them with just one dash or do camelCase or whatever. Doesn’t really matter. Just be consistent and document it.
- Describe the
__element
with a word or two. - Add
--modifiers
if necessary. - Discussed in the upcoming article: Avoid lots of __elements unless you can’t avoid it. For example,
.card__title__link__progress__icon
is a little excessive. - Discussed in the upcoming article: You can mix classnames that are parts of two blocks. For example, if it’s a
.button
block, but it’s also a.card__button
element, you can use both in the HTML.
That’s the Basics: Next Steps
There’s plenty more to class names than using BEM though. I have some tips on how to create class names that are descriptive, useful, and modular, and why that’s so important.
Connect with me on Twitter to get alerted when the next article is posted. Until then, if you want to take a deep dive into BEM, @StuRobson has a big ol’ list of BEM Resources.