loading...
markdown guide
 

In traditional webapps (i.e. webapps built before CSS encapsulation was invented), every CSS rule is shared by the entire app. This creates a few problems:

1) the "acupuncture effect": you modify a style on a button on page A, and suddenly an input on page C is broken. If you've worked on a large web project you've probably got a few gray hairs because of this.
2) fragmentation: one developer uses really explicit class names, e.g. .button-on-the-checkout-page-underneath-the-subtotal, another uses brief class names, e.g. .btn, and yet another uses IDs instead of classes (shudder).
3) fighting the cascade: you write some styles for an element, save, reload, and none of the styles have any effect. You inspect the page and someone else's styles have greater specificity than yours. You have to invent a random way to add specificity to your rule so that your styles will show up, without also wrecking every other element that uses the old styles.

BEM is not a plugin, a library or a framework. It's a set of rules you can adopt to make CSS easier to work with in your project. It stands for "Block, Element, Modifier" and, in short, it gives you the following rules:

1) Every CSS selector should use a single unique class name, not a tag, an ID, or an attribute.
2) Every element in your app should have its own special class.
3) An app is a set of components (known as "blocks" in BEM), and each component has several HTML elements (the E in BEM). Sometimes elements look different depending on the state of your app (different states are "modifiers" in BEM).
4) CSS classes are constructed like this: block__element--modifier. Hyphens are used for multi-word blocks, elements, or modifiers.

So a component in an AngularJS app that follows BEM could look like this:

<div class="week-calendar">
  <div class="week-calendar__header"></div>
  <div class="week-calendar__body"></div>
  <div class="week-calendar__actions">
    <button class="week-calendar__save"
      ng-class="{ 'week-calendar__save--saving': ctrl.saving }">
      Save
    </button>
  </div>
</div>

And the stylesheet would look like this:

.week-calendar { height: 200px; width: 300px; }
.week-calendar__header { height: 40px; }
.week-calendar__body { height: 140px; }
.week-calendar__actions { height: 20px; }
.week-calendar__save { background-color: green; cursor: pointer; }
.week-calendar__save--saving { background-color: gray; cursor: default; }

Or, with a preprocessor like SASS:

.week-calendar {
  height: 200px;
  width: 300px;

  &__header { height: 40px; }
  &__body { height: 140px; }
  &__actions { height: 20px; }
  &__save {
    background-color: green;
    cursor: pointer;

    &--saving {
      background-color: gray;
      cursor: default;
    }
  }
}

When you use BEM, you can look at any class name and know what element it applies to. Specificity never gets out of control, because each element has its own class. And styles meant for specific components won't affect other parts of the app. If you don't have access to CSS encapsulation via a modern solution like Vue, React, CSS Modules, or Angular 2+, this is a great way to keep your style sheets sane.

 

Hey Isaac,

thanks for your explanation,
especially for the part about the traditional problems.

 
 
 

Great explanation, thanks!
Just a question, from a readability point of view, you'd say that it is valid to use even in React or other frameworks?

 

That's a hard one. Last I checked, the "official" solution for styling React apps is CSS-in-JS, which uses the HTML style attribute, which makes BEM irrelevant. However, if you decide to style your app with traditional CSS files (or <style> tags), then yes, BEM is valid.

As far as other frameworks, it depends. Angular 2+ and Vue (with Single File Components) have CSS encapsulation, so BEM, while still valid, is probably solving a problem you don't have.

There are a few other good CSS architectures worth considering as well, like SMACSS and Atomic. And rolling your own is fine too.

 
Classic DEV Post from Jun 19 '19

Is GraphQL the future of APIs?

Graphs are everywhere! What are the main benefits of the data graph structure? Is GraphQL the future of APIs?

Dave O'Dea profile image
"Do things that are hard enough to make you fail."
JOIN DEV NOW

We are a community