Пишем БЭМ правильно

#WebCampOdessa

Igor Zenich, iDeus.

Пишем БЭМ правильно

iDeus
Зачем?

ещё один доклад про БЭМ…

БЭМ — семантичный!

Что он несёт?!

Pepelsbey

Имена БЭМ-классов создают дополнительный уровень логики

Есть DOM-дерево, а есть БЭМ-дерево.

<input class="big_red_button order-button">
<input class="order-button b-checkout__submit">
    

О чём будем говорить?

  1. Как вручную сверстать «по-БЭМ»
  2. Как не писать классы типа device-template-generic-indicator-control-slider-bar-d :)

Кстати, а зачем нужен БЭM?

BEM CSS *

* CSS подмножество БЭМ

Full stack BEM

bemjson, bemhtml, bem-tools, вот это вот всё…

Full stack BEM?

Когда он будет вам нужен — вы это сами поймёте.
Это будет момент, когда вам надоест писать html руками и вы захотите его генерировать.

Пример верстки по БЭМ

Изначальная вёрстка →

Похоже на БЭМ, да?

Давайте приглядимся

Повышение специфичности

:(

bit.ly/not-bem

Непонятость БЭМ

Методология не менялась

.block

Независимый блок

НБ или просто блок, это самодостаточный элемент страницы, который при перемещении в другое место на странице или на другую страницу не теряет своей самодостаточности.

БЭМ.Форум, Независимый блок

Правила независимости блока

  1. для описания элемента используется class, но не id
  2. каждый блок имеет префикс
  3. в таблице стилей нет классов вне блоков
БЭМ.Форум, История создания БЭМ (часть первая)

Как его таким написать?

Просто писать стили тупо на каждый блок.

БЭМ хорош тем, что позволяет не забивать голову ерундой с каскадом, а сосредоточимся на семантике и логике кода.

А с препроцессорами БЭМ позволяет писать еще и очень чистый и логичный код.

Как проверить?

Просто навести на блок в инспекторе кода.
У него не должно быть каскада.

.block__element

Элемент

Элемент – это часть блока, отвечающая за отдельную функцию.
Он может находиться только в составе блока и не имеет смысла в отрыве от него.

bem.info, Методология

DOM-дерево

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

DOM-дерево

.ul {}
.ul > li {}
.ul > li > a {}
.ul > li > a > span {}
    

БЭМ-дерево

<ul class="menu">
  <li class="menu__item">
    <a class="menu__link">
      <span class="menu__text"></span>
    </a>
  </li>
</ul>
    

БЭМ-дерево

.menu {}
.menu__item {}
.menu__link {}
.menu__text {}
    

БЭМ дерево — чистая логика

БЭМ-дерево не зависит ни от чего, даже от размещения в документе.

БЭМ-дерево не привязано к визуальному представлению блоков, оно отображает только логику, это и есть новый уровень семантики!

.block__el__el__el

Так #b_ поняли и используют зарубежом

Я тоже раньше так писал

      .form-buy-results__to-city__slider__tab__column_buy
    

Так делать нельзя

Как надо?

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>
    <div class="block__elem3"></div>
</div>
    

А в CSS

.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
    

Элемент у элемента?

Если вам нужно сделать элемент у элемента, значит вам нужно:

Есть 2 варианта как это переписать

<div class="block">
    <div class="block__elem1">
        <div class="block__elem1__elem2"></div>
    </div>
</div>
    

1. Бить на блоки!

Делать новый блок

<div class="block1">
    <div class="block2">
        <div class="block2__elem"></div>
    </div>
</div>
    

2. Рубить ветки!

Делать БЭМ-дерево с 1-ой вложенностью элементов

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

Типичная ошибка

Попытка вложить имя элемента в имя блока

Чтоб «схитрить» и «как-будто не вложить», написать не .block__el1__el2 а .blockel1__el2 или .block__el1el2. Так нельзя.

.block {}
.blockel1 {}
.blockel1__el2 {}
    

Будут проблемы при переносе

Будут проблемы при переносе

Попытались перенести «странный элемент» в другое место - получили элемент что завис «в воздухе» без блока-родителя

<div class='someblock'>
    <div class='blockel1__el2'></div>
</div>
    

Так можно делать только если .blockelem сохранит логический смысл при переносе в другой блок.

element > element нельзя в CSS, но можно в HTML!

Обратите внимание - вы не можете вкладывать элементы в элементы в CSS, но можете и должны вкладывать элементы в элементы в HTML! DOM-дерево и БЭМ-дерево могут быть разными.

Запрет есть исключительно про нейминг!

БЭМ-дерево на то и дерево, что поддерживает вложенность, поэтому в БЭМ-дереве, разумеется, разрешается вкладывать элементы в элементы, блоки в блоки, блоки в элементы.

Vladimir Grinenko, @tadatuta

Хватит!
Мы не за теорией сюда пришли.

Мы написали BEM-дерево:

<div class="block">
    <div class="block__elem1">
        <div class="block__elem2"></div>
    </div>
    <div class="block__elem3"></div>
</div>
    

Нет каскада:

.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
    

Модификация

6 видов

  1. Модификатором
    • модификатором блока
    • модификатором элемента
  2. Контекстом (т.е. каскадом от блока выше)
  3. Уровнем переопределения (добавлением-перезаписью файла стилей)
  4. Миксованием (добавлением классов других блоков)
    • включая глобальный класс

Просто добавляйте модификатор!

<div class="block-name__elem_key_value">
    

А для элементов — делай каскад от модификатора.

Модификаторы для элементов, можно?

Если речь идет о простых правках, типа «активный пункт меню», то да, можно:

<a class="menu__link menu__link_state_active">
    

Булевые модификаторы

Кстати в таких простых случаях, можно писать модификаторы просто одним словом:

<a class="menu__link menu__link_active">
    

Но подумайте, может это новый блок?

БЭМ допускает ошибки

Самые популярные ошибки

1. block__el__el

Например, слайдеры очень часто верстают дикой вложенностью.

2. Повышение специфичности

В html как-будто всё ok:

<div class="block">
  <div class="block__el">
    

А на деле сели в машину и сгорели:

/* CSS */
.block .block__el {}
    

3. Стили вне блоков

<ul class="menu checkoutForm big myfuckingclass-bold">
    

Почему это ошибки?

Да потому что из-за этого потом тяжелей вносить правки и сложно переместить блок в другое место.

Как мне?...

Вывести текст из WYSIWYG?

Как назначаются стили для типографики? Не будешь же назначать каждому тегу какой-то класс?

Artur Kornakov, @fliptheweb

Добавить .b-text блоку родителю

И использовать каскад.

.b-text h2 {}
.b-text p {}
.b-text img {}
.b-text ul li {}
    

Конечно при большом желании можно настроить визивиг, тот же TinyMCE, чтоб он добавлял нужные имена классов в тегах из визивига.

Задавайте вопросы: ru.bem.info/forum

Пример переверстки по БЭМ (упрощенный)

Диалекты БЭМ

Вот это вот всё на 5 минут:

Префиксы

b-, l-, g-, i-, h-, m-, js-

Придумывайте любые правила
Они нужны вам только для пространства имен.

Альтернативный синтаксис и camelCase

Многим нравится зарубежный формат модификаторов, через „--“, он читабельней.

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

Альтернативный синтаксис и camelCase

А через camelCase – ещё читабельней!

<a class="blockName__elementName--state_active">

Сокращенные модификаторы

Сокращенные модификаторы

Правильно писать так:
.block-name__elem_key_value

Или так:
.blockName__elem--key_value

Сокращенные модификаторы

Но некоторых из тех, кто пишет код вручную, такие модификаторы бесят нечитабельностью кода:

<div class="block-name block-name_key1_value1 block-name_key2_value2 block-name_key3_value3">

Сокращенные модификаторы

…и отсутствием дуракоустойчивости:

<div class="block-name_key1_value1 some-another-block">

Сокращенные модификаторы

Им хочется так:

<div class="block-name -key1_value1 -key2_value2 -key3_value3">

Сокращенные модификаторы

<div class="blockName__elem.-key_value">
.blockName {
  &__elem {
    &.-key_value {
    }
  }
}
    

Миксы!
Full BEM Stack!

JS-блоки

$('.js-fancybox').fancybox();
    

Вы можете создавать свои гайдлайны

Это всё БЭМ

Спасибо!

Igor Zenich, iDeus

Презентация: delka.github.io/talks/webcamp/2015/bem/

Powered by Shower