Почему лучше верстать в соответствии с БЭМ — практические примеры

в 15:23, , рубрики: bem, css, css3, БЭМ, верстка, яндекс, метки: , , , ,

Про БЭМ (методология написания CSS от ЯндексБлок__Элемент_Модификатор ← наиболее правильная запись расшифровки) нынче можно услышать на каждом шагу. Дело оказалось благим и покатилось по миру. Яндекс даже полез в W3C (связано это или нет — не знаю, но надеюсь, что да).

Думаю многие, кто ещё не пробовал, но прочитал описание БЭМ, задаются справедливым вопросом: «какая практическая польза от всего этого действа?» На самом деле, не смотря на то самое развёрнутое описание, конкретно уловить основную «фишку» довольно сложно. Описано конечно много плюсов и общее ощущение от методологии положительное, и кажется, что вроде как и не плохо бы попробовать, но нехватает чего-то конкретного. Прямо вот примера на живом что ли. Вот у меня сайт, вот вёрстка не по БЭМ, почему я должен всё менять? Особенно, если учесть тот факт, что БЭМ в принципе отметает все селекторы кроме классов, неужто за это время столько умных мужей в W3C не осознали, что всё настолько неправильно?

За сим возьму на себя смелость привести несколько примеров с которыми вы (конечно если вы каким-то образом связаны с вёрсткой) сталкиваетесь, не побоюсь этого слова, ежедневно. И что изменится в таких ситуациях если бы вёрстка была изначально выполнена в БЭМ.

Немного о БЭМ

Вкратце вся система БЭМ укладывается в 2 тезиса (принципа/правила):

  1. Нет селектора кроме класса — т.е. никаких стилей повешанных на теги, ID и прочее, только классы.
  2. Нет вложенных селекторов — т.е. никаких .class1 .class2{ display: none; }, всё определяется 1 (одним) селектором класса (плоская/одноуровневая структура стилей/селекторов).

Вот и всё. Вся остальная система — это способ выжить при таких ограничениях.

Естественно такая компания как Яндекс не могла просто так придумать себе геморрой чтобы с ним мучиться до конца дней — для этой системы были причины и именно о них (некоторых из них, с точки зрения простого смертного) я попробую рассказать.

Реюзабельность (повторное использование)

Собственно всё именно из-за этого. Особенно первое правило. Но дальше на обещанных примерах.

Пример 1

Допустим вы заказали вёрстку на аутсорсе. Или вы вошли в проект, который существует давно и всё уже свёрстано до вас. В общем на руках типичные стили вроде:

.content a{
  color: green;
}

и всё работает, но — добавили аяксов и решили AJAX линки в контенте делать без подчёркивания и другим цветом. Мы не можем решить эту проблему добавив класс ajax-link к аякс ссылкам — CSS так не работает. Стиль ссылки в контенте описан селектором из 2х элементов, а это больше чем наш один стиль. Поможет a.ajax-link, если будет стоять в css файле после предыдущего определения.

Теперь предположим, что content это не класс а ID — думаю с таким тоже сталкивались не раз.

#content a{
  color: green;
}

Чтобы «победить» эту запись предыдущий способ не поможет придётся использовать этот id — #content .ajax-link, т.к. id в документе должен быть уникален и, стало быть, его вес выше других селекторов.

Пример 1pro

Т.е. чтобы перебить такое:

#buy-form fieldset .buttons input.submit{
  color: green;
}

и сделать, скажем, скруглённые углы у одной кнопки — вам нужно будет написать что-то ещё более длинное, но с использованием #buy-form.

Пример 2

Допустим у нас есть стили вроде таких:

.content h1{
  font-size: 18px;
}
.content h1 a{
  color: green;
}
.content h1 a span{
  text-decoration: none;
}

И оказывается, что логическая структура страницы изменилась и h1 теперь стал h3 или вообще div, но графическое отображение при этом должно остаться прежним (юзеру — юзерово, яндексу — яндексово). Т.е. для подобного действия потребуется изменить 1 тег в HTML вёрстке и 3 стиля.

Работа БЭМ

Тут на передовую выходят все прелести БЭМ позволяющие использовать как природную каскадность (наследование вложенными элементами стилей родительских элементов) CSS так и возможность изменить/использовать повторно в другом окружении элементы.

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

Думаю вы уже начинаете догатываться, что сейчас получится.

Пример 1 и 1pro

Согласно первому принципу имя тега не может быть селектором (для 1) также как и id (для 1pro) добавляем сюда второе правило и стиль ссылки в контенте вырождается до:

.content__link{
  color: green;
}

Примечание: согласно нотации БЭМ Блок content содержит Элемент ссылки link их разделяют двойным подчёркиванием.

По нашей легенде нам нужно внести изменения в ссылку. Т.е. модифицировать её. Для этого нужно ниже определения стиля смой ссылки .content__link в CSS записать её модификатор, допустим так:

.content__link{
  color: green;
}
.content__link_ajax{
  color: red;
  text-decoration: none;
}

Примечание: согласно нотации БЭМ Модификатор отделяется от Элемента одиночным подчёркиванием.

Т.е. тег будет выглядеть примерно так:

<a class="conten__link content__link_ajax" href="#">Ещё сообщения</a>

Пример 1pro выглядел бы где-то так:

.buy-form__submit{
  color: green;
}

Минусы

Естественно ни что не идеально и концепция БЭМ тоже. В первом случае нам придётся писать класс у каждой ссылки, что не пришлось бы делать при классическом подходе, но опыт показывает (кстати на это часто ссылаются в самом руководстве), что лучше всё же их прописать. Тем более, что сейчас HTML страницы редко когда целиком пишутся руками, так что придётся просто добавить несколько стилей в ваш движок. Ну и, конечно, всегда же есть стили по-умолчанию. Ни что не мешает прописать их в начале CSS файла (тот же сброс стилей). Главное чтоб никакой теговый селектор не был вложенным, только первый уровень и только плоская структура.

Пример 2

Тут уже всё очевидно, но для полноты картины — стили в БЭМ выглядели бы примерно так:

.content-header{
  font-size: 18px;
}
.content-header__link{
  color: green;
}
.content-header__link-text{
  text-decoration: none;
}

По задачам второго примера у нас выходит, что чтобы выполнить задачу нам вообще стили трогать не надо — достаточно изменить 1 тег HTML вёрстки. Собственно в этом месте лишнее прописывание стилей становится оправданным…

Выводы

Немного личного опыта. Превая попытка разобраться была… первой попыткой. Я пытался понять что, зачем и куда + работа с Twitter Bootstrap и я верстал сам. Потом пошёл на другой проект где вёрстку стали давать готовую, но надо рихтовать при введении новых фишек. Вот тут я отчётливо ощутил все проблемы классических стилей. В итоге я просто стал заменять их на БЭМ по мере необходимости. Одно совершенно очевидно — кастомизировать и повторно использовать БЭМ несомненно легче. А отрыв стилей от семантики (те же теги заголовков, выделения и т.п.) позволяет менять теги не беспокоясь о внешнем виде — в большинстве случаев он не разрушится (если версталось по БЭМ полностью без учёта стилей тегов) или будет легко поправим, а значимость элементов для поисковой индексации можно будет изменять.

Как перейти, если конечно если вы решили принять БЭМ в своё сердце.

  • Если вам дали готовую вёрстку и нужно что-то править — ничего не мешает вносить изменения в согласии с БЭМ — ведь это всего-лишь классы. Если это будет продолжаться долго, то постепенно все стили сконвертируются в нужный стандарт.
  • Я попросил шефа требовать от исполнителя вёрстку в БЭМ (и вам советую делать так же). Ничего сложного в ней нет да и исполнителю будет полезно освоить (если ещё не освоил), а жить станет легче.

Автор: qnub

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js