Есть DOM-дерево, а есть БЭМ-дерево.
<input class="big_red_buttonorder-button"><input class="order-button b-checkout__submit">
device-template-generic-indicator-control-slider-bar-d :)* CSS подмножество БЭМ
bemjson, bemhtml, bem-tools, вот это вот всё…
Когда он будет вам нужен — вы это сами поймёте.
Это будет момент, когда вам надоест писать html руками и вы захотите его генерировать.
НБ или просто блок, это самодостаточный элемент страницы, который при перемещении в другое место на странице или на другую страницу не теряет своей самодостаточности.
- для описания элемента используется class, но не id
- каждый блок имеет префикс
- в таблице стилей нет классов вне блоков
Просто писать стили тупо на каждый блок.
БЭМ хорош тем, что позволяет не забивать голову ерундой с каскадом, а сосредоточимся на семантике и логике кода.
А с препроцессорами БЭМ позволяет писать еще и очень чистый и логичный код.
Просто навести на блок в инспекторе кода.
У него не должно быть каскада.
Элемент – это часть блока, отвечающая за отдельную функцию.
Он может находиться только в составе блока и не имеет смысла в отрыве от него.
<ul><li><a><span></span></a></li></ul>
.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 {}
БЭМ-дерево не зависит ни от чего, даже от размещения в документе.
БЭМ-дерево не привязано к визуальному представлению блоков, оно отображает только логику, это и есть новый уровень семантики!
.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>
.block {}.block__elem1 {}.block__elem2 {}.block__elem3 {}
<div class="block"><div class="block__elem1"><div class="block__elem1__elem2"></div></div></div>
<div class="block1"><div class="block2"><div class="block2__elem"></div></div></div>
<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 сохранит логический смысл при переносе в другой блок.
Обратите внимание - вы не можете вкладывать элементы в элементы в CSS, но можете и должны вкладывать элементы в элементы в HTML! DOM-дерево и БЭМ-дерево могут быть разными.
БЭМ-дерево на то и дерево, что поддерживает вложенность, поэтому в БЭМ-дереве, разумеется, разрешается вкладывать элементы в элементы, блоки в блоки, блоки в элементы.
<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 {}
<div class="block-name__elem_key_value">
А для элементов — делай каскад от модификатора.
Если речь идет о простых правках, типа «активный пункт меню», то да, можно:
<a class="menu__link menu__link_state_active">
Кстати в таких простых случаях, можно писать модификаторы просто одним словом:
<a class="menu__link menu__link_active">
Например, слайдеры очень часто верстают дикой вложенностью.
В html как-будто всё ok:
<div class="block"><div class="block__el">
А на деле сели в машину и сгорели:
/* CSS */.block .block__el {}
<ul class="menu checkoutForm big myfuckingclass-bold">
Да потому что из-за этого потом тяжелей вносить правки и сложно переместить блок в другое место.
Как назначаются стили для типографики? Не будешь же назначать каждому тегу какой-то класс?
.b-text блоку родителюИ использовать каскад.
.b-text h2 {}.b-text p {}.b-text img {}.b-text ul li {}
Конечно при большом желании можно настроить визивиг, тот же TinyMCE, чтоб он добавлял нужные имена классов в тегах из визивига.
b-,
l-,
g-,
i-,
h-,
m-,
js-…
Придумывайте любые правила
Они нужны вам только для пространства имен.
Многим нравится зарубежный формат модификаторов, через „--“, он читабельней.
<a class="block-name__element-name--state_active">
А через 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 {}}}
$('.js-fancybox').fancybox();