Про БЭМ (методология написания CSS от Яндекс — Блок__Элемент_Модификатор ← наиболее правильная запись расшифровки) нынче можно услышать на каждом шагу. Дело оказалось благим и покатилось по миру. Яндекс даже полез в W3C (связано это или нет — не знаю, но надеюсь, что да).
Думаю многие, кто ещё не пробовал, но прочитал описание БЭМ, задаются справедливым вопросом: «какая практическая польза от всего этого действа?» На самом деле, не смотря на то самое развёрнутое описание, конкретно уловить основную «фишку» довольно сложно. Описано конечно много плюсов и общее ощущение от методологии положительное, и кажется, что вроде как и не плохо бы попробовать, но нехватает чего-то конкретного. Прямо вот примера на живом что ли. Вот у меня сайт, вот вёрстка не по БЭМ, почему я должен всё менять? Особенно, если учесть тот факт, что БЭМ в принципе отметает все селекторы кроме классов, неужто за это время столько умных мужей в W3C не осознали, что всё настолько неправильно?
За сим возьму на себя смелость привести несколько примеров с которыми вы (конечно если вы каким-то образом связаны с вёрсткой) сталкиваетесь, не побоюсь этого слова, ежедневно. И что изменится в таких ситуациях если бы вёрстка была изначально выполнена в БЭМ.
Немного о БЭМ
Вкратце вся система БЭМ укладывается в 2 тезиса (принципа/правила):
- Нет селектора кроме класса — т.е. никаких стилей повешанных на теги, ID и прочее, только классы.
- Нет вложенных селекторов — т.е. никаких
.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