Menu

How to Design Your Website's CSS Using BEM

How to Design Your Website's CSS Using BEM

If you've ever worked on the front-end of any modern day website, then no doubt you've probably seen the following CSS format.

.card{

}


.card .card-title{

}

.card-title{


}

.card .card-title .card-subtitle{

}

Pretty standard CSS you might think. And truthfully, it looks like much of the CSS that I've written both professionally and non-professionally.

For the most part, it works. But it is not without its shortcomings. For one, it pretty much locks you into a certain hierarchy in the DOM. From the CSS above, it follows that any .card-title element must appear inside of a .card element.

And that a .card-subtitle element must appear inside of a .card-title and subsequently inside of a .card element.

Logically it does make sense that a card-title would exist inside of a card parent. But a card-subtitle doesn't necessarily have to belong to a card-title.

If any of those restrictions change at some point in the future, then that CSS will break as well, making it difficult to redesign a website.

The other issue that you will inevitably face is that of conflicts. The CSS standard allows for the same class name to be implemented multiple times in a single CSS file (or multiple files). It then cascades itself in a downward fashion merging all unique properties into one final set. That same flexibility is what also what creates the potential for conflicting style rules.

You might have multiple card-title's scattered throughout a single project with slight differences, and maintaining each one of those can be a time-consuming task.

Now that we know a few issues that implementing standard CSS might bring, let's take a look at how the BEM methodology might solve for these challenges.

Block, Element, Modifier

BEM isn't anything that you download or npm install. It's essentially a system. A system designed to give some level of standardization to your CSS files. Because as you saw in my example above, CSS can get messy pretty quickly.

BEM (Block, Element, Modifier) is a component-based approach to web development. The idea behind it is to divide the user interface into independent blocks. This makes interface development easy and fast even with a complex UI, and it allows reuse of existing code without copying and pasting because every unique element in a sense has its own unique class.

Everything is a class and there are no nested elements with this design. This ensues that there is no strict binding between the CSS and the layout elements in the DOM.

Block

The block portion of BEM is really at the heart of the entire thing.

Blocks are functionally independent components that can stand on their own. That include anything from control elements that you use site wide, to custom components that only appear once.

Essentially, the block is functionally unique and won't have a chance at conflict later on.

In the particular case of my homepage seen above, blocks can include the logo at the top of the page, the navigation bar to the right of that and the news feed, which also appears in multiple places throughout the site.

Other elements that aren't necessarily going to appear anywhere else, such as the popular news feed to the right, can either have its own block, or it can be considered an element of the home page block.

The only real question you have to ask yourself when naming blocks is if that particular element belongs to another. If it can stand alone, then it can be a block.

Element

Elements in the BEM stack refer to elements that belong to a block and have no standalone meaning. You can think of them as child elements in a page (or component) that don't necessarily appear in other pages or components.

As an example, let's take a look at a content page on this blog.

All of the elements labeled belong to the content page in this case. There is no chance of conflicting with any other element on the website, because in this case, these specifically belong the content Block.

content -> title
content -> author
content -> category
content -> image

Note that each of the listed elements in the screenshot above, will belong to the same parent block.

But also note that something like an image, can potentially be its own block as well if it has universally shared properties.

Modifier

Modifiers are optional and are used to essentially give state to an element. A few examples would include:

- big
- small
- red
- disabled
- checked

Assuming you had buttons on a page with various states of selection, the following CSS would be used to reference it.

.button{

}

.button--selected{

}

.button--disabled{

}

In this case, you would need to add multiple class selectors to a given button in order to get the desired effect.

<button class="button button--selected">Submit</button>

And because these selectors aren't nested, it does not violate the rules of BEM.

How to implement

Now that we know what each element in the BEM stack refers to, it's time to see just how they are implemented, starting off with the Block.

Blocks can be any valid CSS identifier name and can include single dashes ' - ' in cases where multiple words are needed.

.button{}

.header{}

.content{} .blog-post{}

Blocks can also be used standalone, meaning they don't require an element or a modifier.

Elements come directly after a block and are separated by double underscores (__). Examples being:

.content__title{}

.content__author{}

.content__image{}

Elements can also either be single words, or can be separated by single dashes as well. Again, note that you don't need any modifiers associated with your blocks or elements.

And lastly, modifiers come at the trail end of a BEM block and are separated by double dashes ( -- ) after any given element or block.

Modifiers can come either right after a Block or an Element.

.content__image--small{}

.content__image--large{}

.content__title--bold{}

.button--selected{}

Overall, implementing a BEM standard isn't overly complicated if you follow the few basic rules. A few last words about BEM to close things out.

In Conclusion

BEM is just one of many different methodologies when it comes to writing and organizing your CSS. I've personally used it for large scale corporate projects and it has been hugely helpful in reducing the number of conflicts that were common in the past.

But it does come at a cost. For one, class names will inevitably be much longer than when compared to your average nested CSS format.

But more importantly, you do end up losing the entire nested structure that most web developers are familiar with. The same overly strict nested format, can sometimes improve overall development times, particularly on smaller projects.

But I feel that the benefits far outweigh the cost in this situation. So if you've been having a difficult time managing your CSS, or find conflicts to be an issues, then switching over to BEM might be the next most logical move.

Walter G. author of blog post
Walter Guevara is a Computer Scientist, software engineer, startup founder and previous mentor for a coding bootcamp. He has been creating software for the past 20 years.

Get the latest programming news directly in your inbox!

Have a question on this article?

You can leave me a question on this particular article (or any other really).

Ask a question

Community Comments

No comments posted yet

Add a comment