Over the last few years CSS architecture has taken a much larger role in Front-end development. Whether it be a startup of 3 developers or an enterprise product built up of multiple departments, the requirements of a scalable but easy to use codebase have grown exponentially, which as a result has seen the rise in many different conventions or practices detailing how to write your CSS. One particular methodology I’d like to talk to you about today is the "Block, Element, Modifier” naming convention, or BEM for short.

Built by Yandex, BEM has quickly grown in popularity to become one of the leading examples of how you can structure your CSS in a way that will benefit your organisation or website, but rather than get bogged down on why, I want focus on how. In this post I’ll look to demystify the methodology so you can start using it in your own websites.

The concept

BEM is a naming convention that aims to arm developers with an understanding of how one HTML tag relates to another in any given project. In theory, it makes it very easy for said developer to answer the following types of questions:

  • "Is this heading element significant to the <div> it's wrapped in, or just a coincidence?".
  • "Does this button always belong in the header?".

These are the things BEM can answer lightning fast, and when your codebase starts to grow or you inherit someone else's, you'll be thankful for it.

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.

Quick start guide - en.bem.info

Thinking in terms of components on a page, here's how I break things down. BEM stands for Block, Element, Modifier:

  • Block: This 'block' class is used to signify a component, or a standalone object on the page. Block classes are usually short nouns which define the component.
  • Element: An element always lives within a block, it's a single part of a component that together with others, make up the block's features. Element classes are prefixed by the block's class, followed by double underscores. For example .block__element.
  • Modifier: You may often find yourself repeating multiple components, or blocks that do very similar things but with slight alterations. Maybe Box 1 has a blue background whereas Box 2 has a red background. This is where modifiers come into play, adding an extra hook in our CSS to give that one specific block some extra bits of styling. Modifier classes are prefixed once again by the block's class, but followed this time by double hyphens, for example .block--modifier. They can also be prefixed by the element class if the modifier is specifically modifying that, rather than the entire block, for example .block__element--modifier. I like to reference this as "Block Modifiers vs Element Modifiers".

Whenever I'm explaining to someone how the BEM naming convention works I always fallback to a post from Harry Roberts in 2013 entitled "MindBEMding - getting your head 'round BEM syntax". Within this post, Harry uses the example of how we might structure a person in BEM, if it were a component on your website.

The block level element would be .person as that's the component we're creating. The elements of a person are his/her limbs, so .person__leg, .person__hand, which all belong to a person. Finally, modifiers of a person could be their sex (i.e. .person--female, .person--male) or maturity (i.e. .person--adult, .person--child). These classnames then provide developer's some up front knowledge about the relationship those classes have to one another, rather than having to guess from the CSS properties used.

More importantly, you can then start reusing components for different aspects of your page. Let's say you need to use a 'person' component twice on the page, once for an adult and another for a child. All people have hands, legs and feet so those classes and their styling don't need to change. The only difference is that there may be a few tweaks to these elements, based on the modifier of the component (in this case, the maturity of the person).

Here's how we might break things down. First, we start off with our .person block.

Fig 1: Demonstrating a 'person' component as a BEM block.
Fig 1: Demonstrating a 'person' component as a BEM block.

Next, we have the elements of our component (or 'block'). We then know that all .person__hand and .person__eye components are required to be nested within the .person block.

Fig 2: Demonstrating the various elements of a fake 'person' component.
Fig 2: Demonstrating the various elements of a fake 'person' component.

Finally, we modify the block where necessary, and we then know that the .person--adult class is always declared on a HTML tag with the .person block.

Fig 3: An example of the modifiers of a person component.
Fig 3: An example of the modifiers of a person component.

Real world examples

Enough of that theory stuff, let's think about some real world examples.

The button component

Also known as the .btn component, this is a staple in any interface design requiring call to actions for your users. What's unique about smaller components like these is that they typically don't have many elements, but have a lot of modifiers. Allow me to explain.

Let's take this website as an example. I have four colours in my palette: #efb5b5, #afdeb5, #aed7ea and #f8d892. If I were to use these as modifiers for my buttons I might do something like this.

/* Block */
.btn { /* styling here */ }

/* Modifiers */
.btn--red { background: #efb5b5; }
.btn--blue { background: #aed7ea; }
.btn--green { background: #afdeb5; }
.btn--yellow { background: #f8d892; }

And here's my markup.

<a href="#" class="btn btn--red">Text here</a>

As you can see, there's no reason to add any elements to this component, unless I wanted some sort of icon next to the text perhaps.

<a href="#" class="btn btn--red">
	<span class="btn__icon">&larr;</span>
	Text here
</a>

A note on modifier naming

That looks great, but now I have modifiers that have very distinct purposes that can't change later down the line. Take .btn--red for example, it's very obvious that this class will always make the background red, and any deviation from that wouldn't make sense. So 6 months down the line when I decide I want to use purple for my brand instead of red, I would need to create a whole new class and deprecate the old one. Not a problem for a modifier as small as this, but it still means I need to go through my entire codebase and change any reference of .btn--red to .btn--purple, or similar. Now imagine a larger component with many options, things can quickly get away from us.

A better approach would be to keep classes unopinionated from the styling they're producing. Classes such as .btn--primary, .btn--secondary are far more universal to an ever changing brand and don't infer styling.

The media component

Nicola Sullivan wrote at length about the implementation of the .media element she helped Facebook with back in 2010. The general idea behind this component is that it's a common pattern that you'll see yourself using on many layouts. It's the idea of an image floated to the left of some text, here's an example of the component being used on the Smashing Magazine website, taken from my post on Why the DRY principle isn't always the right answer.

Fig 4: An example of the media object from Smashing Magazine.
Fig 4: An example of the media object from Smashing Magazine.

Our markup would look something like this.

<div class="media">
	<img class="media__img" src="" alt="">
	<div class="media__body">
		<!-- Content goes here -->
	</div>
</div>

And our CSS would introduce the .media--flipped modifer, where you are able to override the default nature of the component and have the image appear to the right of the text.

/* Block */
.media {}

/* Elements */
.media__body {}
.media__img {}

/* Modifiers */
.media--flipped {}

Further reading

I hope this brief primer on the BEM methodology has helped, but if you're still unsure I would recommend looking over the following articles:

Anything to add? Something i could have explained a little better? Let me know in the comments section below.

Until next time 👷


# Related posts

Like what you've seen? Want more? Check out similar posts on Assortment that you may find interesting:


# Comments

  1. #1 Posted:

    Roralee

    You're explanation of BEM is the first I've read that provides enough justification for usage in differentiation with double underscores and hyphens. No other explanation I've come across has covered it except as "convention". I'm still not 100% on board with it but in the future, I'll be much more friendly to and considerate to it use.

    Reply to this comment
    1. #1-1 Posted:

      Luke Whitehouse

      Hi Roralee, thanks for your message. I'm glad to hear that my explanation made things a little easier for you. Admittedly I'm not a big fan of the double underscores/hyphens but I do understand the reasoning. It allows developers to still make use of single hyphens (for example when a component's name is double barrel) without having to confuse others.

      It's worth mentioning that methodologies like BEM are just conventions to make your life easier, if it doesn't work for you or you want to change things up a little then that's great, go ahead and create your own fork of BEM that works for your use cases :)

      Kind regards, Luke

  2. #2 Posted:

    Gregg OD

    Thanks for this.

    I was little confused by the modifier in these examples because they weren't displayed.

    So you have .person and then a modifier would be .person--adult or .person--child

    In html and css how would you modify something like .person__leg of .person--adult? Would you say:

    .person--adult .person__leg{

    } or .person--adult__person__leg{ }

    The current way I do css I would say: .person .leg{ **default styles } .adult .leg{ **adult styles }

    or this underneath the .person styles so it takes preference (cascading style sheets) .person-adult{

    } .person-adult .leg{

    }

    or if you don't want specificity: .person-adult{

    } .person-adult-leg{

    }

    I guess with Sass you can extend styles and what what... which might make more sense for BEM.

    .person height: 40px; width: 40px;

    .leg height: 50px

    .person--adult @extend .person color: green;

    &-leg height: 100px;

    then atleast you would have: .person, .person-adult{ height: 40px; width: 40px; }

    .person--adult-leg{ height: 100px; }

    but doing something like .person--adult__person__leg for each child of .person seems a bit excessive... although very precise.

    Some clarity and examples from anyone would be great :)

    Reply to this comment
    1. #2-1 Posted:

      Luke Whitehouse

      Hi Gregg,

      Thanks for your comment! This question often gets raised when working with a component that requires modifiers for various elements. The general principle I follow is:

      What am I modifying?

      In your example, an adult version of a person would not only be modifying .person__leg but they'd also be modifying other elements such as .person__arm and .person__torso due to the larger stature of an adult against the likes of a child. In this case, I would opt to create a modifier for the entire component, known as a "block modifier", such as .person--adult. I would then either nest all elements within that modifier using Sass, or I'd prefix the element selectors in CSS.

      Here's an example in Sass.

      .person--adult {
          .person__leg {
              // styling for adult leg
          }
      
          .person__arm {
              // styling for adult arms
          }
      }
      

      However, it's worth noting that this will increase your CSS specificity which isn't the best. The alternative to this approach would be to create an "element modifier" for each element that needs altering, such as: .person__leg--adult and .person__arm--adult, however, this would prove cumbersome when working with any form of dynamic data from a CMS so there's always a tradeoff and each project or even component should be approached separately. There is no one size fits all.

      I hope this helps!

      Kind regards, Luke

# Leave a comment

No wookies will get this, its just for your Gravatar image.

Basic markdown supported, go to FAQ for more info.