Кажется, в крупных проектах рунета «БЭМ» становится стандартом де-факто.
Если хочется попробовать и получить некоторые плюсы от разработки в стиле БЭМ, но нет возможности внедрять всю технологическую цепочку, то стоит для начала перенять именование классов. Разумеется, это будет уже не БЭМ. Тем не мене, методом проб и ошибок ребятам из Яндекса удалось выработать хорошую методику именования CSS-селекторов для абсолютно-независимых блоков.
Блок
Канонические имена блоков в БЭМ начинаются с префикса b-
и отвечают на вопрос «Зачем нужен это блок?»:
.b-menu {}
Я в своей практике префикс всегда опускаю, так как лично для меня – это лишние символы не несущие никакой смысловой нагрузки.
.menu {}
Элемент
Элемент – часть блока, которая не имеет смысла вне этого блока и не может быть использована вне него.
<nav class="menu">
<h3 class="menu__head">Menu</h3>
<ul class="menu__list">
<li class="menu__item">Item 1</li>
<li class="menu__item">Item 2</li>
<li class="menu__item">Item 3</li>
</ul>
</nav>
Селектор элементов именуем следующим образом: .имя-блока__имя-элемента.
Модификатор
Модификатор служит для изменения внешнего вида (возможно, и поведение) блока или элемента. Селектор записывается в виде: .имя-блока _тип-модификатора_значение-модификатора или .имя-блока __имя-элемента_тип-модификатора_значение-модификатора
Назначив тегу блока или элемента класс модификатора, можно изменить его внешний вид.
<nav class="menu menu_footer">
<h3 class="menu__head">Menu</h3>
<ul class="menu__list">
<li class="menu__item">Item 1</li>
<li class="menu__item menu__item_state_current">Item 2</li>
<li class="menu__item">Item 3</li>
</ul>
</nav>
Модификатор menu_footer
у блока menu
, например, меняет размер шрифта у меню в подвале страницы
.menu { font-size: 16px; }
.menu_footer { font-size: 12px; }
А модификатор menu__item_state_current
у элемента menu__item
может поменять цвет фона у текущего раздела
.menu__item { background: black; color: white; }
.menu__item_state_current { background: yellow; color: black; }
Модифицировать можно и контекстом. Например, модификатор блока может влиять на элементы этого блока. Важно запомнить, что это можно делать только, если такие блоки не вкладываются друг в друга, иначе не избежать проблем со специфичностью. Так же никогда не модифицируем блок от контекста другого блока. Это лишает блок независимости.
Коментарии к заметке
А кто еще БЭМ использует? Питонщик из Future Colors отметились статьей, да в вакансиях стало встречаться, но чтоб о стандарте говорить… Правда, кто еще?
Знаю, что в «Стратегии» и «Ругионе» внедряют это дело.
В методологии есть определённые плюсы перед хаотичной версткой и сборкой страниц. А раз альтернатив нет, то автоматически БЭМ я отношу к стандартам.
Обновление:
Я всё-таки склонен отделять БЭМ как методологию, от БЭМ-инструментов. Первое гораздо популярнее, чем второе. Да и «ещё БЭМ» или «уже не БЭМ» — разве это важно? Важно, чтобы выбранная схема хорошо работала для тех, кто её использует, и БЭМ тут — отличная основа.
Альтернативы, кстати, есть — SMACSS и OOCSS. В обоих есть интересные моменты. И я бы решительно рекомендовал ознакомиться со всеми.
Я для себя взял всё интересное из трёх методологий и пока мне нравится, что получилось.
Интересный документ и набор ссылок. Спасибо.
Я предпочитаю использовать такие каскады только для контента, созданного пользователем через WYSIWYG, например. Всё остальное, скорее всего, шаблонизируется разработчиком, и нет проблемы навесить нужные классы. Очень легко можно попасть в ситуацию, когда потребуется повышать специфичность CSS селектора только из-за того, что где-то выше в иерархии задан каскад, влияющий на дочерние элементы (вложенные списки, например).
В качестве эксперимента для блога я написал фильтр, который парсит статью и добавляет каждому тегу соответствующий класс, чтобы потом по одному селектору класса можно было бы их декорировать. Мне эта идея очень понравилась.
Так это же модификаторы. Чем синтаксис БЭМ не угодил?
Вот тут я полностью согласен. Меньше «копипасты», больше лени!
В целом твои тезисы сводятся к тому, что из жестких правил БЭМ вычленяются какие-то упрощения, обоснованный только меньшим количеством букв в классах. Не скажу, что я за или против этого. Все мы человеки со своими слабостями.
Состояния не зависят от блока. Это бывает удобно. Модификаторами я тоже пользуюсь, конечно.
Мы в своем проекте тоже используем БЭМ и очень этому факту рады: взял кусок вставил куда надо и он работает без неожиданностей
Просто верстальщики маленьких сайтов, коих подавляющее большинство, как правило, не задумываются о последующем развитии проекта. Занимаясь одним проектом годами начинаешь остро осознавать, что хорошо организованный HTML/CSS/JS не просто блажь, а банальная необходимость.
Сам уже больше двух лет назад старался использовать длинные уникальные название для классов, чтобы не было конфликтов у блоков на разных страницах. Но, признаюсь, мне как раз не хватало такой стройности и однозначности в названиях.
Так же долгое время не мог избавиться от большой каскадности в селекторах. Умом понимал, что это плохо, а руки продолжали писать
.page .article p em { }
.Я думаю, что всё неприятие БЭМ пройдёт со временем.
Неприятие в основном как раз у тех самых разработчиков хомячков :)
а вот как сочетать верстку АНБ и принцип DRY (don’t repeat yourself), позволяющий использовать какие-то элементарные конструкции в разных местах?
скажем, блок, в котором картинка слева и некоторое текстовое описание справа…?
DRY тут не работает. Всё оформление должно быть сконцентрировано в одном месте.
Вот Артём Сапегин называет общие вещи «примесями». Лично я думаю, что для обычных сайтов это не плохо. Я тоже предпочту один раз описать
clearfix
,hidden
и что-то ещё, а потом пользоваться этими классами там, где они нужны.ок. успокоил.
мне в числе прочих понравилось как сделан тот же sotmarket.ru. хотя там и используются таблицы для основной разметки, там виден такой подход к наименованию классов, как
l-container
,g-clearfix
и т.п., подразумевая, как мне кажется, l- layout и g- global.вроде бы подобный подход видел у Артема Поликарпова…
еще заметил за собой, что порой туплю как назвать класс у блока, чтобы потом не было мучительно больно, не пришлось переделывать и т.п.
Все 4 года существования LOVATA Group используем методологию БЭМ, еще со времен, когда она называлась просто «независимые блоки».
Мы активно используем смешивание нескольких блоков на одном DOM-узле.
Например, у нас есть блок i-clear, который подмешивается в другому блоку или его элементу.
Всё можно выразить блоками и в этом суть БЭМ. Никаких «диких» классов вне блоков не существует.
Мы в итоге ушли от префиксов, отличных от b- и i-.
Если надо сделать раскладку таблицами, это блок b-layout-table, который подмешивается к элементам другого блока.
Ага, примерно понятно. Такие утилитарные классы получается представляют собой блоки из одного элемента. Действительно такая концепция покрывает все варианты без привнесения дополнительных сущностей.
Виталий, а подскажи про пересечение блоков на таком примере:
Элемент
div.b-block-1__text
получается должен так же иметь какой-то класс и от b-block-2 . Правильно я понимаю?Не обязательно. Если этот DOM-узел имеет значение в контексте блока, то можно ему задать класс от этого блока.
Можно вообще так сделать:
Уведел эту статью из комментария Владимира к моей. Возможно, кому-то еще будет интересно почитить мои мысли по поводу верстки незавсимыми блоками http://blog.lebedev-design.ru/indi-blocks