Why using BEM for your CSS is a good idea

Not even those of you with long memories will remember that I wrote a blog post in 2015 about using the Block Element Modifier technique when writing CSS. To save you the trouble, I wrote the following.

…I saw immediately that the concept is based on weak coding principles, not code simplicity and reusability…

Four years and countless projects further down the road, I see from my website statistics that a retraction is due. I’ll say now that I’m not back-pedalling, but have found the application of BEM as a concept much more helpful since learning from Nico‘s experience and in particular through a return to hand-coding without using a pre-defined CSS framework.

My original point stands – that if you have the time and if you aren’t working on a big site, using semantic CSS classes for specific combinations of elements can make sense. But this is rarely the case for a programmer using CSS these days. Sites are much more complex than they were ten or even five years ago, so a little structure can save you a lot of hassle.

By applying a scoping class to an element and its set of constituent elements, you can quickly avoid specificity conflicts, and by using this scope, you will end up writing less CSS. (You’ll still run into specificity conflicts when competing with disorganised CSS from third-party plugins, but that’s a separate issue.) Working with WordPress’ Gutenberg editor this year, I (and my colleagues at work) have achieved an exceptionally lean CSS structure for our projects.

So, how does CSS scoping work? By applying a master class name to the outer HTML element and by adding variations on this master class name to the appropriate subelements.

<article class="c-article">
 <header class="c-article__header">
  <h1 class="c-article__title">Article title</h1>
 </header>
 <div class="c-article__content">
  …
 </div>
</article>

The generated CSS for this element could look like this. No nesting, no issues with descendant selectors, and rules based purely on simple class names, independently of the actual HTML structure.

.c-article {
  border: 1px solid #eee;
  padding: 1rem;
  background-color: #f0f0f0;
}

.c-article__title {
  font-size: 2rem;
  margin: 0 0 1rem;
}

Where did I go wrong back in 2015? Take my price element from that blog post as an example.

<a class="btn" href="/prices/">
 <span class="btn__price">$9.99</span>
 <span class="btn__text">My product</span>
</a>

I bemoaned the fact that we might want to apply a common styling to all price elements, stating that the following CSS would probably be necessary.

.btn__price, .list__price, .header__price, .teaser__price {
 font-weight: bold;
 font-size: 110%;
}

That’s not true: what I overlooked at the time is that I can add multiple classes to the same selector. By using an identifying prefix to the class name (o for objects, c for components), I can combine two to describe each element in a semantic way. Thus, my HTML changes to this.

<a class="c-pricebutton o-button o-button--primary" href="/prices/">
  <span class="o-button__price">$9.99</span>
  <span class="o-button__text">My product</span>
</a>

In this instance, I can apply the following styles using SCSS. As you can see, the button rules have simple button styling applied, with a o-button--primary modifier to change the colour styles. The larger size and bold font style comes from the c-pricebutton class name.

.c-pricebutton {
 font-weight: bold;
 font-size: 110%;
}

.o-button {
 display: inline-block;
 padding: .25em;
 color: blue;
 background-color: white;
 &--primary {
  color: white;
  background-color: blue;
 }
}

In this example, you could potentially make the same styling change to increase the size and weight of the button using a o-button--large modifier in place of c-pricebutton. However, I feel that this removes a level of semantic definition in favour of a directly visual one, which is inadvisable. Keep the rules for how an element should appear in the CSS, and use purely semantic elements and semantic element class naming in the HTML.

Comments

There are 8 comments for this entry.

  1. Thanks for the update. For me you sample line shows me that BEM adds needless complexity and naming decisions to the web coder. I do, however, see an advantage in generated html code. I’m working on a bespoke framework and could see a use for this. Still for the careless web designer the number of classes is overwhelming and not helping.

    I’m still not confinced I could save time when hand coding certain parts of my web app.

    • Ok. No one is forcing you to change your way or working if it’s efficient for you and everyone else who might work on your project. Using BEM in our projects has saved us (on average) 25% in terms of time needed for going back to work on older projects, and saves us a noticeable amount of time when first coding.

  2. I see. I just wanted to let you know that I would like to become as convinced as you, a turned infidel. :-) I’m just wondering what I would gain from BEM. that 25% was established how exactly?
    How do you see the generated html (cms or otherwise) code angle? I don’t see me typing and remembering those long lists of classes but my php wouldn’t mind just a bit.

    • Using classes instead of element selectors makes rules re-usable. Using a BEM structure will rarely add or remove the number of CSS rules you have to write. The speed gains are in the logical and repetitive structure of your files, components and class names, so it becomes a lot easier and quicker to find where your rules are defined. It’s always part of the programming to have to make decisions on naming conventions, so BEM makes this step easier.

      • . I can see some benefit in that. It is possible to use class .c-pricebutton on a button, an a, or even (g*d forbid) a intput[type=submit]. But as it also could be used on a section an article or h4 it is losing its semantic button-ness to speak. Why move something to the classlist where it is already available as tag. (never understood those.h1, .h2 and .h3 classes from Bootstrap either)
        But I guess if it works for you—and numerous others—why not.

        • Because it’s down to the developer to ensure that the class name is correctly applied. If the BUTTON later gets changed to an A tag, then the CSS doesn’t need to be changed. The Bootstrap classes allow you to visually style e.g. an h2 so that it remains hierarchically correct, but looks like an h3. This is a very common requirement in all the projects we work on.

  3. So, to put it in perspective, ultimately at the html side we only need , and a couple of and . We will style headers as and for paragraphs and so on, yielding maximum flexibility.

  4. My examples were filtered out. We only need div tags and classes like h1 and p for headers and paragraphs and so on.

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.