EM

Meet.js Poznań #32

Who am I?


const me = Object.freeze({
  name: 'Sergey Bolshov',
  position: 'FrontEnd Developer',
  workPlace: 'Apptension',
  email 'bolszow@gmail.com',
  githubUsername: '@bigsergey',
  country: 'Kazakhstan'
});

What is BEM?

Block Element Modifer - is a component-based approach to web development. The idea behind it is to divide the user interface into independent blocks.

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>

What is wrong with CSS?

  • global selectors
  • no explicit dependenciеs
  • selectors specificity / priority
  • complex selectors
  • isolation from parent element / cascade
  • isolation from global selectors
  • code duplication
  • removing unused code

BEM Block

BEM Element

BEM Modifier

Yandex naming convention

.{block-name}

.{block-name}__{element-name}

.{block}_{block-modifier}

.{block-name}__{element-name}_{element-modifier}

<div class="menu menu--theme-xmas">
    <span class="menu__item"></span>
    <span class="menu__item menu__item--hidden"></span>
</div>

Harry Roberts' style

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

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 {}

BEMMix

  • Combine the behavior and styles of multiple entities without duplicating code.
  • Create semantically new UI components based on existing ones.
<!-- several blocks -->
<div class="menu head-menu"></div>

<!-- a block and an element of another block -->
<div class="menu">
  <div class="link menu__link"></div>
</div>

<!-- block with modifiers -->
<div class="link link--active link--theme-xmas"></div>

BEM: The Good Parts

.signup__account__user-name__input { ... }

How to fix block__elem__elem?

BEFORE

AFTER

<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__elem2"></div>
    </div>
</div>

<!-- OR -->

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

CSS styles

HTML

CSS


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

.block .block__element {
  ...
}

Wrong CSS styles

HTML

CSS


<div class="block">
    <div class="block__element">
    </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>

  • Namespace - .block.mod or ul li {} ul > li > ul >li
  • Mixes - <div class="menu__item button active">
  • Code searching - find active or 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)

  • 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>

Can I create a global modifier applicable to any block?

.menu {
  @include reset-list;
}

.menu__item {
  @include reset-list-item;
}
...
.list {
  @include reset-list;
}

.list__item {
  @include reset-list-item;
}

How to reuse a button?

<form class="search-form">
  <input type="text" class="input">
  <button type="submit" class="search-form__button button button_theme_lite">
    Search
  </button>
</form>

<form class="auth">
  <input type="text" class="login">
  <input type="password" class="password">
  <button type="submit" class="auth__button button button_theme_dark">
    Sign in
  </button>
</form>
.search-form__button {
    margin: 30px;
}

.auth__button {
    margin: 40px;
}
.button_theme_lite {
    background: #fff;
}

.button_theme_dark {
    background: #000;
}

OOCSS

  • Separate structure and skin
  • Separate container and content

SMACSS

  • Base
  • Layout (.layout-)
  • Module (.example)
  • State (.example.is-active)
  • Theme

SUIT CSS

  • u-utilityName
  • ComponentName
  • ComponentName--modifierName
  • ComponentName-descendentName
  • ComponentName.is-stateOfComponent

Atomic

  • quarks (.links)
  • atoms (.buttons)
  • molecules (.banner)
  • utilities (.reset)

BEM

  • block
  • block__element
  • block--modifier

Benefits

  • Modularity - independent blocks.
  • Reusability - composing independent blocks in a different way and reusing them.
  • Structure - simple and understandable structure in your CSS code.

Full stack BEM

  • ENB
  • bemhint
  • bem-tools
  • bemmet
  • bem-sdk
  • BEMJSON
  • BEMHTML
  • BEMTREE
  • i-bem.js
  • gemini
  • Angular-BEM
  • postcss-bem-linter (SUIT and BEM)

Thank You! Stay BEMed!

Useful resources

BEM Meet.js | Sergey Bolshov

By Mateusz Jabłoński

BEM Meet.js | Sergey Bolshov

  • 643