Frontender Magazine

Учимся любить БЭМ

Должен признаться: когда я впервые услышал о БЭМ, я подумал, что идея как-то не очень. Зачем так усложнять именование в CSS? Можно же называть классы проще: .form-group или .accordion. Какой смысл заморачиваться классами вроде .accordion__child и .accordion__child--highlighted?

В январе я работал над одним проектом с моим коллегой Йелле (Jelle), который в своем коде использует БЭМ-синтаксис. Сначала я сомневался в этом подходе, но, так как он был ведущим HTML/CSS разработчиком проекта, ему и карты в руки.

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

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

Логика БЭМ (Блок — Элемент — Модификатор):

Более развёрнутое объяснение можно найти тут.

Это даёт следующие преимущества:

Конечно, у БЭМ есть свои недостатки:

С моей точки зрения, для сайтов, которые поддерживают один или несколько человек, БЭМ необязателен, и я скорее буду использовать normalize.css и простое именование.

Для больших проектов БЭМ — отличный выбор. Он потребует некоторых усилий в начале работы, но сэкономит массу времени в долгосрочной перспективе. Так что вперёд!

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Johan Ronsse
Автор:
Johan Ronsse
Twitter:
@johan_ronsse
Сaйт компании:
http://mono.company/
Сайт:
http://johanronsse.be/
GitHub:
Wolfr
Антон Немцев
Переводчик:
Антон Немцев
Сaйт:
http://frontender.info/
Twitter:
@silentimp
GitHub:
SilentImp
Skype:
ravencry

Комментарии (56 комментариев, если быть точным)

Автар пользователя
VovanR

Почему модификатор отделяется двойным дефисом --, а не подчеркиванием _?

Автар пользователя
iamstarkov

Такая нотация получила большее распространение на западе

Автар пользователя
VovanR

Ясно, так и подумал.

Гибкость методологии отпугивает новичков. Все пишут, что фишка в гибкости: структурируй проект как хочешь, структурируй файл стилей как хочешь. Хочешь так, хочешь сяк. Новички залипают на элементарных вещах. Вроде

.post &__header &__header-name &__header-name-text

Или тупят, придумывая названия блокам и элементам. Выделить элемент в блок или оставить элементом. Застайлить блок каскадом или добавить модификатор оформления:

``` .header__badget color: red

.badget__text
    box-shadow: 0 0 0 1px green

```

Или

``` .badget_theme_super color: red

.badget__text
    box-shadow: 0 0 0 1px green

```

И еще куча мелочей.

Автар пользователя
VovanR

Подсветка что-то поломалась. Лучше тут посмотреть мои примеры: https://github.com/FrontenderMagazine/learning-to-love-bem/issues/1#issuecomment-108407641

Автар пользователя
iamstarkov

я не понял, как это относится к нотации

Автар пользователя
Inkluter

Странная вещь, БЭМ любят только определенные девелоперы на территории СНГ, на западных ресурсах я встречал упоминания о БЭМ буквально несколько раз.

Автар пользователя
saschalion

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

Когда заходишь на хорошо сделанные сайты, даже невооружённым глазом видно, что внутри БЭМ :)

Я верстаю только на БЭМе вот уже около 4х лет, и очень им доволен, также не согласен, что он годится ТОЛЬКО для больших проектов. Он подходит как для больших, так и для маленьких, будь то сайт-визитка, лэндинг или корпоративный сайт.

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

Автар пользователя
nikbelikov

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

Автар пользователя
SilentImp

@Inkluter на западе BEM не без форсирования Yandex набирает популярность и достаточно быстро. Статьи: - An Introduction to the BEM Methodology - A New Front-End Methodology: BEM - Scaling Down The BEM Methodology For Small Projects - The Evolution Of The BEM Methodology - MindBEMding – getting your head ’round BEM syntax - BEM 101 - BEM and SMACSS: Advice From Developers Who’ve Been There - OOCSS, ACSS, BEM, SMACSS: what are they? What should I use? - Organizing CSS: OOCSS, SMACSS, and BEM - The Modular CSS (BEM/OOCSS) naming conundrum - The benefits of BEM CSS - BEM Basics - Mastering CSS: BEM and ITCSS

И это только верхушка айсберга. Мне кажется, что такой интерес к методологии о многом говорит.

Автар пользователя
drakmail

@VovanR кстати, а есть какие-нибудь best practices по именованию и выбору структуры в БЭМ?

Автар пользователя
sherkhan

Не знаю, про нотации запада, но в наших реалиях, модификатор должен состоять из 2-х слов и отделяться одинарным подчеркиванием __modtype_modname все остальное от лукавого и к БЭМу отношение имеет лишь опосредственное. А еще есть связка блок-элемент (когда блок является элементом) итд. В общем и целом тема не раскрыта

Автар пользователя
sherkhan

*_modtype_modname

Автар пользователя
VovanR
Автар пользователя
iamstarkov

Не знаю, про нотации запада, но в наших реалиях, модификатор должен состоять из 2-х слов и отделяться одинарным подчеркиванием __modtype_modname

как будто на западе реалии проще, просто в данном случае у них будет два модификатора и всё --mod-1 и --mod-2

Автар пользователя
iamstarkov

все остальное от лукавого и к БЭМу отношение имеет лишь опосредственное.

ты так говоришь, как будто бэм религия, а не инструмент

Автар пользователя
iamstarkov

Всем могу посоветовать ещё вот этот небольшой ресурс по бэму http://getbem.com/

Автар пользователя
yunusga

Для опробования методологии подойдет BEML. Также доступны плагины для Gulp и Grunt. Это небольшой HTML препроцессор (или постпроцессор) облегчающий написание BEM разметки путем расширения HTML синтаксиса.

Автар пользователя
yunusga

Плюс, можно для ознакомления, в дополнение к BEML, попробовать jquery-bem

Автар пользователя
iamstarkov

Плюс https://www.npmjs.com/package/b_ и http://noteskeeper.ru/1143/

Автар пользователя
Tom910

Сейчас часто сталкиваюсь с проблемой выделения блока и часто приходится думать, это все еще элемент или уже блок. И в какой отдельный блок можно поместить, что иногда выливается в - my-element__sub-element__sub-sub-elemnt

Автар пользователя
yunusga

@Tom910, возможно из sub-element или sub-sub-elemnt лучше сделать блок и доопределять его модификатором (в БЭМ даже ссылка является блоком)?

Автар пользователя
tadatuta

Я попробовал тут https://ru.bem.info/forum/158/ ответить на частые вопросы про БЭМ, часть из которых повторилась и в этом тредике. Велкам!

Ну и если возникнут новые — не стесняйтесь задавать их на форуме, мы оперативно там отвечаем.

Автар пользователя
vyushin

В статье упор идет на принципы написания селекторов и непосвященному человеку может показаться, что это и есть весь БЭМ, но это только 10% от всего БЭМ. :)

Автар пользователя
iamstarkov

это смотря с какой стороны смотреть, если с той с которой бэм можно использовать то он pure css а значит это весь бэм. Если с другой «фулл-бэм-стек», с которой тебя весть воркфлоу менять придётся, то конечно css-часть бэма это только часть бэма.

Автар пользователя
tadatuta

@iamstarkov методологическая часть БЭМ является историей про компонентный подход и говорит о том, что блок как минимальная полезная сущность в современном вебе включает не только стили, но и JS (созвучно с web components). А дальше ее можно развивать на тесты, документацию и любые шаблонизаторы.

Автар пользователя
olegcherr

Незачем пытаться полюбить бэм таким, какой он есть в оригинале. Возьмите основные принципы, а всё остальное переделайте как вам удобно. Вот моя реализация: http://azagroup.ru/azabem-css-method/

Пользуюсь ею уже несколько лет. Разработка стала гораздо приятнее.

Автар пользователя
sherkhan

@olegcherr Никаких "b-head-stripe_theme_simple-red" здесь не будет. - будет e-block-elem_modyfer

"БЭМ - это не буква и в начале имени класса" (с). uppercase и camelcase в css не просто моветон, но и конкретное ЗЛО!

Автар пользователя
sherkhan

*не буква "b" в начале имени класса" - punto балуется

Автар пользователя
iamstarkov

uppercase и camelcase в css не просто моветон, но и конкретное ЗЛО!

ват. почему?

Автар пользователя
sherkhan

@iamstarkov потому что classname !=ClassNaMe потому что догма, постулат итд. уже истоков не найду почему так или иначе, но главная причина указана в начале

Автар пользователя
iamstarkov

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

Автар пользователя
sherkhan

@iamstarkov конечно, дело каждого. тут никто не имеет права навязывать ). Но использовать id для стилизации, заглавные буквы в именовании класса и пропагандировать идеологию радикального национализма - это.... крайне нежелательно )

Автар пользователя
olegcherr

@sherkhan На момент написания статьи там были именно такие гигантские классы. Насколько мне помнится, данный пример я взял из документации. А если посмотреть классы на главной Яндекса, то без проблем можно встретить такое:

class="b-yabrowser-promo______wrap b-yabrowser-promo__wrap_right".

Поэтому я и занялся доработкой, которая подходит именно мне ))

Автар пользователя
olegcherr

Блин. Предварительный просмотр тут показывает совершенно не то, что получается на самом деле. Я имел ввиду так:

class="b-yabrowser-promo__wrap b-yabrowser-promo__wrap_right"

Автар пользователя
olegcherr

По-поводу uppercase и camelcase согласен с @iamstarkov

Автар пользователя
sherkhan

"olegcherr гигантские классы никуда не делись, браузеру параллельно сколько бит содержится в имени класса. 2 или 20. разница в рендере будет в наносекундах измеряться. а в плане чтения и сапорта кода - мы моем часы выиграть

Автар пользователя
sherkhan

@olegcherr но в целом - вы правы. все, кто влюбился в БЭМ, в какой-то момент его делают "под себя". лично я опускаю именование блока или элемента в модификаторе "_state_active" мне хватает, а если юзать less, то двойной амперсанд вообще решает! жаль, sass так не умеет

Автар пользователя
iamstarkov

двойной амперсанд вообще решает! жаль, sass так не умеет http://lesscss.org/features/#parent-selectors-feature-multiple-

насколько я понял это обычный parent_selector и он есть во всех CSS-процессорах

Автар пользователя
sherkhan

@iamstarkov не правильно понял .block { &&_modtype_modname {} }

прогони в лесс и в сасс - и все станет ясно

Автар пользователя
sherkhan

@olegcherr что за маниакальная настойчивость вставить префикс b- в название класса? это из бэма мохнатых веков, когда он еще анб назывался

Автар пользователя
iamstarkov

если тебе нужен двойной родительский селектор, то ты увеличиваешь вес селекторов и теряется вся суть бэма

Автар пользователя
olegcherr

@sherkhan Лично я -b не использую совсем. Я использую -l, -e, -j, -p, -g.

В ссылке, что я привёл выше, это всё описано.

Автар пользователя
sherkhan

@iamstarkov модификатор не может существовать отдельно от блока или элемента - отсюда и двойной селектор

Автар пользователя
sherkhan

@olegcherr хрен редьки не слаще - зачем? опустим "i" для js

Автар пользователя
iamstarkov

модификатор не может существовать отдельно от блока или элемента - отсюда и двойной селектор

и как это обязывает селектор быть .block.block_mod_val? в css можно таргетить просто и по .block_mod_val

Автар пользователя
sherkhan

@amstarkov противоречит методологии. потому что .button.button_position_nav и .image._position_nav два разных блока с двумя разными модификаторами

Автар пользователя
sherkhan
  • .image.image_position_nav - сори, подустал за неделю )
Автар пользователя
sherkhan

а в целом - модификатор не сущность и не моет существовать отдельно

Автар пользователя
iamstarkov

втф. или я тебя не понял, или кто-то из нас понимает бэм неправильно

Автар пользователя
sherkhan

@iamstarkov block width: 10 или block_mod width 20 что сработает?

Автар пользователя
sherkhan

@iamstarkov вечер пятницы - я могу не совсем корректно излагать мыслю. Повторюсь "block width: 10 или block_mod width: 20 что сработает?"

Автар пользователя
sherkhan

@iamstarkov попробую перевести на русский есть блок, он может быть зеленым и мы пишем или "зеленый блок", или просто "зеленый". а если этот блок был черным, то что важнее?

Автар пользователя
SilentImp

@sherkhan в отличии от @iamstarkov я не работал в Yandex, но я тоже использую именно один селектор и мне кажется это правильно и соответствует методологии.

.block{} .block_mod{}

— правильно.

.block{} .block.block_mod{}

— не правильно.

Можно создать топик на https://ru.bem.info/forum/ и спросить у непосредственно причастных. Что скажете?

Автар пользователя
SilentImp

@iamstarkov @sherkhan имеет ввиду что больший вес селектора в случае .block.block_mod{} гарантирует применение правила модификатора вне зависимости от положения правил блока и модификатора относительно друг друга. Мне кажется, что достаточно того что бы правило модификатора шло после блока в css. В общем случае мы можем это гарантировать.

Автар пользователя
iamstarkov

Спасибо @SilentImp

Автар пользователя
yunusga

@SilentImp давай топик и ссылку на него