BEM Methodology

BEM is abbreviation for Block-Element-Modifier. It's a methodology that can help you to organize your CSS codebase - doesn't matter if you are one person or a project team. Check why, how and how not to use it.

Basics

Syntax consists of the following pattern:

block__element--modifier
  • block component wrapper (required)
  • __element child element inside block (optional)
  • --modifier block or element variants (optional)

Examples

Following example contains basic rules that need to be kept in your mind.

index.html
<a href="#" class="btn btn--danger">
  <span class="btn__ico">x</span>
</a>

<a href="#" class="btn btn--success">
  <span class="btn__ico btn__ico--small">x</span>
</a>
style.css
// Block
.btn {
  display: inline-block;
  background: white;
}

// Modifier
.btn--danger {
  background: red; 
}
.btn--success {
  background: green; 
}

// Element
.btn__ico {
  display: inline-block;
  font-size: 0.8em;
}

// Element + Modifier
.btn__ico--small {
  font-size: 0.6em;
}
style.scss
// Block
.btn {
  display: inline-block;
  background: white;

  // Modifier
  &--danger {
    background: red; 
  }
  &--success {
    background: green; 
  }

  // Element
  &__ico {
    display: inline-block;
    font-size: 0.8em;

    // Element + Modifier
    &--small {
      font-size: 0.6em;
    }
  }
}
Wrong

One of the most common mistakes is to create multiple element nesting.

<a href="#" class="btn btn--danger">
  <span class="btn__ico">
    <!-- wrong -->
    <span class="btn__ico__text">..</span>
  </span>
</a>
// wrong
.btn__ico__text { .. }
Good

The right solution is to create flattened structure without multiple nesting.

<a href="#" class="btn btn--danger">
  <span class="btn__ico">
    <!-- good -->
    <span class="btn__text">..</span>
  </span>
</a>
// good
.btn__text { .. }

Advanced

Once you start to create real applicaton with BEM some decisions issues probably appears. Read more to find out the most common ones.

Don't mix components

If there is already button btn component, don't create new one like article__btn.

Wrong
<div class="article">
  <div class="article__text">..</div>
  <!-- wrong -->
  <div class="btn btn--small article__btn"></div>
</div>
Good
<div class="article">
  <div class="article__text">..</div>
  <!-- good -->
  <div class="btn btn--small btn--secondary"></div>
</div>

Don't create component dependent on the context

If you need btn component to have specific behaviour inside another article component, create new modifier covering other required cases.

Wrong
.btn { .. }

.article {
  // wrong
  .btn { .. } 
}
Good
.btn { 
  // good
  &--another { .. }
}

.article { .. }
This article is currently work in progress, last update: September, 2016