BEM

let's write bem correctly

BEM

Block Element Modifer - is a methodology that helps you to achieve reusable components and enables code sharing in the frontend

Created by Yandex in 2005

Code that is hard to maintain

// How those classes are related?


<div class="media user premium">
  <img class="img photo avatar" src="" />
  <p class="body info">...</p>
</div>

... and code that is easy to maintain

// It's BEM baby

<div class="media user user--premium">
  <img class="media__img user__photo avatar" src="" />
  <p class="media__body user__info">...</p>
</div>

BEM BLock

Text

Text

Text

BEM Block

BEM Element

BEM Modifier

Yandex naming convention

<div class="block-name__elem-name_mod-name_mod-val">

Yandex naming convention

<div class="block-name">

// block name

HTML
<div class="menu">...</div>


CSS
.menu { color: red; }

Yandex naming convention

<div class="block-name__elem-name">

// element name

HTML
<div class="menu">
    ...
    <span class="menu__item"></span>
</div>


CSS
.menu__item { color: red; }

Yandex naming convention

<div class="block-name__elem-name_mod-name_mod-val">

// boolean modifier & key-value type modifier

HTML
<div class="menu menu_hidden">...</div>
<div class="menu menu_theme_xmas">...</div>

CSS
.menu_hidden { display: none }
.menu_theme_xmas { color: green; }

Harry Roberts' style

<div class="block-name__element-name--state_active">

CamelCase style

<div class="blockName__elementName--state_active">

'Sans underscore' style

<div class="blockName-elementName--modName--modVal">

You can use prefixes

  • b- common blocks
  • l- layout grids
  • h- holsters
  • js- js blocks
  • qa- for tests
  • etc.

Bem example

Dom-Tree

BEM-Tree

// html
<ul>
  <li>
    <a>
      <span></span>
    </a>
  </li>
</ul>

// css
.ul {}
.ul > li {}
.ul > li > a {}
.ul > li > a > span {}
// html
<ul class="menu">
  <li class="menu__item">
    <a class="menu__link">
      <span class="menu__text"></span>
    </a>
  </li>
</ul>

// css
.menu {}
.menu__item {}
.menu__link {}
.menu__text {}

BEM: The Good Parts

.signup__account__user-name__input { ... }

?

WRONG!

Before

After

How to fix block__elem__elem?


<div class="block">
    <div class="block__elem1">
        <div class="block__elem1__elem2"></div>
    </div>
</div>
<div class="block1">
    <div class="block1__elem1 block2">
        <div class="block2__elem1"></div>
    </div>
</div>

// OR

<div class="block1">
    <div class="block1__elem1">
        <div class="block1__elem2"></div>
    </div>
</div>

Html

Css

CSS styles


<div class="block">
    <div class="block__element">
    </div>
</div>

.block .block__element {
  ...
}

Html

Css

Wrong CSS styles


<div class="block">
    <div class="block__elememt">
    </div>
</div>
/* bad */
.block .block__element {
  ...
}

/* good */
.block {
  ...
}
.block__element {
  ...
}

Why the modifier CSS classes are not represented as a combined selector?

<div class="block mod">...</div>

or

<div class="block block--mod">...</div>

Any ideas?

  1. Namespace
  2. Mixes - <div class="menu__item button active">
  3. Code searching - find active and button--active

Avoid Sass' @extend

<div class="menu menu--hidden">...</div>

OR

<div class="menu--hidden">...</div>

/* good */
.menu,
.menu--hidden,
.menu--other-modifier {
 // base styles
}

/* better */
.menu {
 // base styles
}
.menu--hidden {...}
.menu--other-modifier {...}
  • CSS (clean and minimum sized)
  • Descriptive
  • Flexibility and consistency (same styles applied twice for two modifiers)

Can I create a global modifier applicable to any block?

visible, invisible, opacity50 and etc.


// css
.hidden { display: none }
/* ... */
.block { display: block }

// html
<div class="block hidden">
    you still see me
</div>

<div class="block mod1 mod2">
    you have no control over the block
</div>

Don’t be afraid of long class names

Focus on self documenting class names. Don’t be afraid of long class names! His advice – “Use long, descriptive class names over short names that don’t document themselves.”

Serge Herkül,  developer at Teamweek – WebsiteTwitter

Bem Tools

  • bem-core
  • bem-components
  • bem-bl
  • bem-mvc
  • bem-history
  • gemini 

angular-bem

A set of directives to simplify your workflow with BEM-markup in Angular-based applications.

How to use

bower install angular-bem
or
npm install angular-bem
// include module
angular.module('app', ['tenphi.bem']);

// create a simple markup
<body ng-app="app">
  <div block="my-block" mod="{ modName: 'value' }">
    <div elem="my-element" mod="{ modName: 'value', secondModName: true }"></div>
  </div>
</body>

// result
<div class="my-block my-block--mod-name_value">
  <div class="my-block__my-element 
              my-block__my-element--mod-name_value 
              my-block__my-element--second-mod-name">
  </div>
</div>

Install

Using BEM filter with Emmet

Alternatives

  • Object-Oriented CSS (OOCSS)
  • Scalable and Modular Architecture for CSS (SMACSS)
  • Atomic CSS (ACSS)
  • Style tools for UI components (SUIT CSS)
  • etc.

Q & A

 

Stay BEMed!

 

Useful links

BEM Block Element Modifier

By Sergey Bolshov

BEM Block Element Modifier

  • 1,493