Methodologies

Yevhen Isakov

Why?

With or without?

OOCSS

Object
Oriented
CSS

OOCSS

Scalable and
Modular
Architecture for
CSS

SMACSS

Block
Element
Modifier

BEM

Absolutely
Independent
Blocks

Reasons

  • Every element on page may be repeated and may be cloned to any project page
  • CSS Cascade slows page rendering
    .parent .child { ... }
    .child { ... }
  • Class selectors are faster than tag selectors
    header { ... }
    .header { ... }
  • Every block name should be unique

Everything on page is block

Everything on page is block

Block

  • Block name should be written with digits and latin letters in lowercase
  • .block { ... }
    
    .header { ... }
  • Block name can be composite
    .block-wrapper { ... }
    
    .header-menu { ... }
  • Block name creates namespace for elements and modifiers
  • header
    <header class="header"> ... </header>
    .header { ... }
  • navigation
    <nav class="navigation"> ... </nav>
    .navigation { ... }
    ...
  • footer
    <footer class="footer">...</footer>
    .footer { ... }

Element

  • Element name separates from block name by double underline
    <div class="block">
        <div class="block__element"></div>
        <div class="block__yet-one-element"></div>
    </div>
    .block__element { ... }
    
    .block__yet-one-element { ... }
  • Elements may contain other elements
    <article class="article">
        <header class="article__title"> ... </header>
        <aside class="article__data">
            <span class="article__author"> ... </span>
            <time class="article__pubdate"> ... </time>
        </aside>
    </article>
    ...but not logically!

DOM Tree

BEM Tree

header
  • logo
  • menu
  • global-icon
  • search-icon
<header class="header">
    <a class="header__logo"></a>
    <ul class="header-menu"> ... </ul>
    <a class="header__global"></a>
    <button class="header__search"></button>
</header>

Modifier

  • Both blocks and elements may have modifiers
    <div class="block_mod"> ... </div>
    
    <div class="block__elem_mod"> ... </div>
    
    <li class="menu__item_state_active"> ... </li>
  • Modifier separates from block name or element name by one underline
    <div class="block-name_mod-name"> ... </div>
    
    <div class="menu_state_hidden"> ... </div>
  • By default, modifiers are written in format key_value
  • Short modifier format — logical boolean modifier
    <div class="block_visible"> ... </div>
    
    <div class="slider__element_current"> ... </div>
  • Modifier can be added only to existing block or element, it DOES NOT exist by itself
  • 
      <div class="tabs">
        <ul class="tabs__ul">
          <li class="tabs__title">
            <a class="tabs__link tabs__link_state_active"> ... </a>
          </li>
          <li class="tabs__title">
            <a class="tabs__link"> ... </a>
          </li>
          <li class="tabs__title">
            <a class="tabs__link"> ... </a>
          </li>
        </ul>
        <div class="tabs__item tabs__item_active">... </div>
        <div class="tabs__item">... </div>
        <div class="tabs__item">... </div>
        <div class="tabs__item">... </div>
      </div>

Most important things

Nested logical structure is supported ONLY for blocks

Most important things

Element's element DOES NOT exist in BEM
<div class="block">
    <div class="block__elem1">
        <div class="block__elem2">
            <div class="block__elem3"></div>
        </div>
    </div>
</div>
.block { ... }
.block__elem1 { ... }
.block__elem2 { ... }
.block__elem3 { ... }
<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>
    <div class="block__elem3"></div>
</div>

Most important things

Actually, does NOT matter how block separates from element and modifier
.block-name__elem-name_mod-name_mod-val

.blockName__elemName—modName

.blockName-elemName_modName_modVal
Every variant is correct in BEM

Block or element?

  1. If code fragment may be used repeatly and does not depend on another page components, you should use BLOCK.
  2. If code fragment can not be used by itself, without its parent entity (block), in most of cases you should use ELEMENT

Mixing

  • button
    .button { ... }
    order
    .order { ... }
    
    ...
    
    .order__button { ... }
  • result
    <button class="order__button button"></button>

Preprocessors ♥ BEM

.block {

    &__elem {

        &_some_mod {
            foo: bar;
            }
        }

    &__yet-one-elem {
        bar: baz;
        }

    &_mod {
        baz: bar;
        }

    &_mod &__elem {
        foo: bar;
        }
    }

BEM is also about

  • BEMHTML
  • BEMJSON
  • BEM Tools
  • BEM Components
  • BEM Project Structure
  • i-bem.js
  • ...and that's not all

Evolution never stops...

Thank you!

Yevhen Isakov