Python/Django разработчик
0,0
рейтинг
21 сентября 2012 в 19:23

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

CSS*
Про БЭМ (методология написания 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_type_ajax{
  color: red;
  text-decoration: none;
}

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

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

<a class="conten__link content__link_type_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 и я верстал сам. Потом пошёл на другой проект где вёрстку стали давать готовую, но надо рихтовать при введении новых фишек. Вот тут я отчётливо ощутил все проблемы классических стилей. В итоге я просто стал заменять их на БЭМ по мере необходимости. Одно совершенно очевидно — кастомизировать и повторно использовать БЭМ несомненно легче. А отрыв стилей от семантики (те же теги заголовков, выделения и т.п.) позволяет менять теги не беспокоясь о внешнем виде — в большинстве случаев он не разрушится (если версталось по БЭМ полностью без учёта стилей тегов) или будет легко поправим, а значимость элементов для поисковой индексации можно будет изменять.

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

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


PS: Примечания в квадратных скобках добавлены на основании комментариев vithar.

Я.Субботник в Екатеринбурге
Вадим Лопатюк @qnub
карма
52,2
рейтинг 0,0
Python/Django разработчик
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (285)

  • +44
    Я вижу только отвратительную читабельность, низкую скорость разработки и потенциальные проблемы при поддержке БдсЭМа.
    Описанные вами преимущества с лихвой покрываются препроцессорами типа SASS и LESS.
    • 0
      Вся прелесть заключается в том что одно другому не мешает. Это просто способ записать название стиля, который избавляет от головняков с его применением. Всего лишь… Никто не мешает (наоборот, даже рекомендуют) использовать компиляторы с поддержкой переменных, функций и т.д.
      • +5
        Вы сами в статье заметили, что от головняков это не спасает, а наоборот — создаёт новые на совершенно пустом месте (пример со ссылками).
        Кроме того, существует мнение, что семантика — это не только название тега, но и совокупность его атрибутов, в том числе class и id, от которого вообще предлагают отказаться.
        • +1
          «Существует мнение» и «поддерживается стандарт» это немного разные категории. Значение тегов и микроформатов описано и официально декларируется поисковиками как поддерживаемые стандарты (см. руководство по оптимизации любого поисковика). Некоторые атрибуты тегов тоже туда относятся, но не id, class, или data-* — т.к. они изначально выступают в роли служебных элементов. Можно подозревать что поисковик придаёт повышенное значение элементу с id «warning»? Даже если так кто заставляет не использовать этот id в коде страницы? Просто не нужно использовать этот id для назначения стилей…
          • 0
            Хоть я и нахожу стандарты исключительно рекомендательными, но раз уж мы о них заговорили — прошу любить и жаловать:
            Elements, attributes, and attribute values in HTML are defined (by this specification) to have certain meanings (semantics).
            http://www.w3.org/TR/html5/elements.html#semantics-0
            • 0
              Простите, а я про что написал?
              • 0
                Вы написали про поисковики:
                Некоторые атрибуты тегов тоже туда относятся, но не id, class, или data-*

                Я вам ответил, как это же выглядит в стандарте HTML5, а именно, что семантика — это совокупность тегов, атрибутов и их значений. И всё туда очень даже относится.
                Поэтому, когда БЭМ лишает меня возможности писать нормальные, логичные классы, использующие каскад, когда он запрещает на идеологическом уровне мне использовать id — я нахожу в этом ухудшение семантики.
                • 0
                  Там написано, что у каждого элемента есть назначение (смысл) и оно обрабатывается браузером/поисковиком и т.д. И id, class, или data-* также имеют свой смысл, а именно — это прикладные элементы для описания классов, идентификаторов и доп. данных для служебного пользования. Собственно даже отсюда вырастает то, что не надо использовать теги и идентификаторы для определения внешнего вида.
                  • 0
                    И, ещё раз, как это согласуется с БЭМом? Вы лично не видите явной семантической пропасти в этой идеологии?
                    • 0
                      А так, что классы — классово, а идентификатору — идентификаторово. Не должен идентификатор использоваться для описания внешнего вида, и тег не должен. Внешний вид тега должен обрабатываться браузером в соответствии с его семантическим значением. А название класса должно использоваться как название класса — для поиска по этому названию в CSS файле описания его внешнего вида — не более того. А ни как не для вычисления особой смысловой значимости этого элемента. Никто не запрещает использовать идентификатор для целей быстрого нахождения элемента в JS, просто не надо на него цеплять нюансы отображения — для этого есть классы…
                      • 0
                        В не поверите, но классы тоже не для этого. На них можно повесить стили с помощью CSS-селекторов, которые позволяют достаточно гибко выбрать элемент для применения правил. Но, так же, стили можно повесить на id или, скажем, на каждого второго члена списка. Вы вправе использовать любые селекторы для стилизации элементов, в том числе по id.

                        Я хочу сказать, что навязывание классов, как единственно-возможного способа задания стилей элементу, ущербно.
                        • 0
                          Тут Вы правы вообще во всём. www.w3.org/TR/html5/global-attributes.html#classes класс — это объявление принадлежности элемента к каким-то классам. И ещё «authors are encouraged to use values that describe the nature of the content, rather than values that describe the desired presentation of the content». И класс это всего лишь один из возможных селекторов. Всё так, и об ущербности я написал в начале статьи — БЭМ это 2 принципа, а вся остальная методология — это способ выжить в этих ограничениях. Всё так и есть…

                          Однако это не меняет положения вещей — работать с БЭМ в части стилизации отображения всё равно проще (и он не отменяет ни LESS ни ID ничего другого). С ним не надо решать задачи, с ним можно просто написать то, что нужно и получить это без хитрых хаков своего же CSS.
                • +1
                  Думаю, в рекомендации скорее говорится о том что для блока авторизации вряд ли подойдёт класс .block1, или например .news. Т.е., по этому классу можно сказать, что это за блок. По БЭМ-именованию с исключеним множества вложенностей в именовании вполне себе можно понять что это за блок и даже какое иерархическое положение он имеет.
                  • +1
                    Да, но сомнительно, что для попапа будут семантичными классы b-popupa b-popupa__without-padding b-popupa_theme_ffffff b-popupa_direction_down b-popupa_is-bem_yes i-bem b-dropdowna__popup b-dropdowna__menu b-popupa_js_inited.

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

                    Для таких целей придумали SASS и LESS, в которых иерархия прослеживается табуляцией, что намного читабельнее.
                    • +3
                      Это корявый БЭМ) Давайте тогда я «не_БЭМ» буду представлять как
                      .myOwnPage #myBlock div div div a {}
                      ? :)
                      • 0
                        Даже этот ужасный «каскад» (как его называют БдсЭМщики) лучше читается, чем приведённый мною «корявый» БЭМ.
                        Да и у кого учиться БЭМу, как ни у его создателей?
                        • 0
                          Так и учитесь. Есть bem.info — там всё подробно, и с хорошими примерами. Куда как лучше составлять своё мнение на чём-то более-менее существенном. Моё сложилось на множестве больших проектов, которыми занималось одновременно много человек, и на том, что те люди, что не использовали БЭМ, после них его полюбили и оценили профит.
                          • 0
                            Более существенном, чем Яндекс.Метрика? habrahabr.ru/post/151931/#comment_5158009
                            • 0
                              Но это же HTML! Классов туда можно набить хоть миллион — HTML от этого не изменится зато изменить внешний вид элемента — элементарно и также элементарно поменять HTML не нарушая внешнего вида.

                              С другой стороны когда у тебя вязанка контекстных селекторов то ни то, ни другое (если там участвуют теги) сделать не просто. Просто потому что сами своими руками прибили себя к этому месту на странице и этим тегам и потом только выкручиваться и переписывать.
                              • 0
                                Но я же про семантику! Любимый момент: b-popupa_theme_ffffff
                                • 0
                                  Вы так ничего и не поняли…
                                • +1
                                  ffffff — название темы, тут может быть любой удобный верстальщику идентификатор.

                                  Замените b-popupa_theme_ffffff на b-popupa_theme_white, если вам так больше нравится.

                                  Только сложно будет подбирать названия цветов, когда основным цветом темы будет какой-нибудь цвет типа #1ab3df.
                            • 0
                              Ну, накосячили верстальщики или разработчики.
                              А говнокод на PHP характеризует PHP?
                    • 0
                      Да, и вы удивитесь, но с БЭМ можно использовать LESS и табуляцию :)
                      • +1
                        <картинка c троллейбусом из хлеба/>
                    • 0
                      Если вы так пишете БЭМ, то вы забиваете гвозди микроскопом.
                    • +1
                      Да, но сомнительно, что для попапа будут семантичными классы b-popupa b-popupa__without-padding b-popupa_theme_ffffff b-popupa_direction_down b-popupa_is-bem_yes i-bem b-dropdowna__popup b-dropdowna__menu b-popupa_js_inited
                      Да, будут семантичны. Объяснить каждый класс отдельно?
            • 0
              Расскажите, каким, по-вашему, должно быть именование классов?
            • 0
              И что вас смущает, например, в:
              .menu
              .menu__item
              .menu__item .link
              ?
              Что несемантично/сложно/непонятно?
              • 0
                Конкретно этот пример — ничем не смущает.
              • 0
                ".menu__item .link" — это ведь уже не БЭМ?
                • 0
                  не БЭМ
                • 0
                  Почему? Блок может содержать и элементы и другие блоки.
                  • +1
                    В статье же «Нет вложенных селекторов — т.е. никаких .class1 .class2{ display: none; }, всё определяется 1 (одним) селектором класса (плоская/одноуровневая структура стилей/селекторов).»
                    Выходит не ".menu__item .link" должно быть, .menu__item_link
                    • 0
                      В статье же «Нет вложенных селекторов — т.е. никаких .class1 .class2{ display: none; }, всё определяется 1 (одним) селектором класса (плоская/одноуровневая структура стилей/селекторов).»
                      В статье ошибка, я ниже про это написал: habrahabr.ru/post/151931/#comment_5165248

                      Запись ".menu__item .link" означает: блок link вложенный в элемент item блока menu.
                  • +1
                    Содержать может, но описывать стиль вложенного блока так всё равно нельзя. Структура CSS должна быть плоской (один и только один уровень) иначе смысл теряется…
                    • 0
                      А как тогда быть с модификаторами? Их нельзя применять к элементу, только к блоку, или я ошибаюсь? А если .link содержит в себе множество элементов, которые я хочу сделать элементами для блока ссылки плюс мне нужно состояние (к примеру активности) для неё? Мне эти элементы тоже привязывать к меню?)
                      • +1
                        Даже не знаю, что сказать и как по букве. Но если мне нужно уникальное состояние для блока — я добавлю модификатор через подчёркивание, если для элемента — я поступлю аналогично.

                        Получается что-то вроде (как сделал бы я и с учётом того что можно отображать вложенность)

                        .menu
                        .menu_highlighted // особое состояние всего меню
                        .menu__item
                        .menu__item_hidden // особое состояние элемента меню
                        .menu__item__link
                        .menu__item__link_active // особое состояние ссылки меню
                        • 0
                          Насколько я знаю, вот так
                          .menu__item__link .menu__item__link_active
                          совсем делать нельзя.
                          Может быть только один уровень вложенности (поправьте меня примером с bem.info, если я не прав).
                          Т.е., м.б. только отношения блок__элемент, но никак не блок__элемент__элемент.
                          • 0
                            Вот знающие люди говорят что можно и я склонен согласиться, т.к. концепцию это не рушит, а понять местонахождение поможет. Но может это стоит делать в особо непонятных случаях, я обычно все внутренние элементы вне зависимости от уровня вложенности именую как блок__элемент — чтоб не разводить демагогию в именах (опять же, может я его потом передвину и чем это лучше вложенных селекторов уже не понятно) да и их обычно в блоке не так чтобы много однотипных на разных уровнях чтоб заморачиваться. Хотя автоматические инструменты наверняка нагеренрят полный путь (я пока не пользовался)…
                            • 0
                              Не вижу явной необходимости прописывать .menu__list__item__link__icon
                              и не встречал такой подход где-либо + создатели, как я понял, тоже против такого (хотя я уверен, что можно модифицировать под себя всё что угодно, но эта дорога реально в ад).
                              • 0
                                Согласен, потому я так у себя не делаю. Иногда лишняя педантичность только вредит :)
                          • 0
                            Не то что бы нельзя… Печаль умножает.
                          • 0
                            Может быть только один уровень вложенности (поправьте меня примером с bem.info, если я не прав).

                            Т.е., м.б. только отношения блок__элемент, но никак не блок__элемент__элемент.
                            Да, всё верно, только один уровень вложенности, может быть только блок__элемент.
                            • 0
                              Добавлю, что речь только об именовании классов. В самом HTML вложенность одних элементов в другие может быть любой глубины.
                      • 0
                        А как тогда быть с модификаторами? Их нельзя применять к элементу, только к блоку, или я ошибаюсь?
                        Модификторы могут быть как у блоков, так и у элементов:

                        .block_mod_value
                        .block__elem_mod_value
      • +2
        БЭМ — это не просто способ записывать названия стиля.
        • +12
          но и попытка горстки людей навязать всем пользоваться их сомнительным корпоративным стандартом?
          • +1
            Вас кто-то что-то заставляет делать?
            • 0
              Надеюсь, что до этого не дойдет, но новость про вступление в W3C в контексте этого топика настораживает.
              • 0
                Во-первых, если они и повлияют там на что, так это с целью избежать костылей типа БЭМа. А во-вторых, там и без них достаточно «горсток людей» со своим мнением.
                • +1
                  Хорошо, я скажу подробнее:

                  1) По-моему, создание подобных костыльных решений как раз поощряет использование того что есть теми, кто считает, что это ущербно, вместо того, чтобы «взбунтоваться» и, действительно, взять и подкинуть нормальную, бескостыльную идею, вроде упомянутых выше less и sass.

                  2) Что касается самого Яндекса и участия его в развитии html/css, то я разделяю ваш оптимизм, поскольку Яндекс это не какая-то бестолковая веб-студия, а компания, собираемая действительно хорошими специалистами, о чем, в том числе, говорят их продукты, которыми я каждый день пользуюсь и остаюсь доволен. Не согласен я только в том, что этот БЭМ является чем-то таким, чем можно поделиться для пользования.
                  Этот набор собственных наблюдений и правил форматирования лучше использовать когда вы наедине и никто на вас не смотрит, иначе через год мы уже будем отучать людей пользоваться в CSS только классами и двойным подчеркиванием в именах, от которого нынешних программистов отучала пользоваться почти каждая книга по программированию.

                  Подытожу:
                  Если Яндекс хочет сделать что-то инновационное с CSS, то я наверняка буду рад, хотя и на данный момент особых сложностей с CSS не испытываю. Но БЭМ — это не расширение, а сужение к плоскому понятию «классы» всего объемного css, с его иерархичными `тэг -> класс -> элемент (id)`, а в сочетании с использованием двойного подчеркивания в именах и моего нежелания доломать себе глаза их считая, я твердо уверен, что это совершенно не решение испытываемой ими проблемы.
                  • 0
                    Я понял, в чем у нас с вами основа непонимания. Я считаю less и sass такими же костылями, как и БЭМ, а вы нет.
                    • 0
                      Я понял, в чем у нас с вами основа непонимания. Я считаю less и sass такими же костылями, как и БЭМ, а вы нет.
                      Я с вами полностью согласен. Вообще, HTML/CSS не предназначался для современного их использования, для создания web-приложений. Если бы они дизайнились сейчас с нуля именно для этого современный web был бы другим. И делать web-приложения было бы существенно проще.
                  • 0
                    двойным подчеркиванием в именах, от которого нынешних программистов отучала пользоваться почти каждая книга по программированию.
                    БЭМ-методология не навязывает использование подчёркиваний для отделения одних сущностей от других, мы можете использовать любые другие сепараторы для отделения имени блока от имени элемента, и модификатора от блока/элемента.

                    Более того, возможность использовать любые другие разделители заложена в bem-tools и это можно настраивать как для всего проекта, так и для любого уровня переопределения в нём.
    • +3
      вы украли мой коммент.
  • +18
    Названия CSS классов БЭМ весят больше чем HTML теги ))
    • +1
      Наверное это тоже можно причислить к минусам…
    • +2
      Ну и что? Большая часть там повторяющиеся фрагменты, которые хорошо сжимаются в gzip.
    • +4
      Можно использовать class mapper, как это например это сделано в Google Closure + Google Soy Templates — размер названий классов сократится до одной-двух букв. Для дебага конечно можно и не обфускейтить названия.
      Кроме того, названия должны быть достаточно информативны, чтобы последующий человек, читающий код, не сходил с ума пытаясь понять, что имелось ввиду. Т.е. длинные имена — не могут быть отмазкой, что так оно весит больше.

      Во что превращаются имена классов после маппинга вы можете увидеть напрямую в YouTube/Gmail/Analytics и другие. Причем Google старается использовать БЭМ тоже, это ОЧЕНЬ облегчает паралельную разработку проекта из тимов размером 50-100 людей. Это не по на слышке.
      • 0
        Стоит уточнить, пока камни не полетели, это не всетаки не в чистом виде БЭМ с БЭМ нотацией, но _очень_ близко к этому.
      • 0
        Причины использования БЭМа Яндексом или Гуглом, в разработке собственных сервисов, предельно понятны и обоснованы.
        Автор статьи же, как и верстальщики Яндекса, рекомендует применять БЭМ везде.
        • +3
          Ну я это предлагаю делать не потому, что люблю яндекс или бегу за всем новым. Я предлагаю это на основе личного опыта. Мне нужно править готовую вёрстку или старую вёрстку. И править БЭМ или править классическую вёрстку это две большие разницы. Правка БЭМ обычно заключается в добавлении класса, а правка классики в перелопачивании половины CSS файла…

          Это взгляд с моего берега. Возможно тем кто просто верстает статику и сдаёт заказчику (у которого кто-то типа меня потом с этим всем работает) и проще налепить по быстрому 10 вложенных тегов и получить деньги, но любви к таким исполнителям у меня не прибавляется (хотя понимаю, что это мало кого волнует).
          • 0
            Главные принципы хорошей вёрстки — это её семантичность, последовательность и читабельность.
            Использование БЭМа значительно понижает 2 принципа из трёх: семантичность и читабельность. И это относится не только к вашим примерам, где от БЭМа только классы, но и к полноценному БЭМу, который навязывает Яндекс.

            От себя рекомендую посмотреть в сторону SASS + Compass и требовать вёрстку именно в них — это избавит вас от вышеописанных проблем, при этом не понижая семантику и значительно повышая последовательность с читабельностью.
            • 0
              1) Читабельность. Смотря на правильно свёрстанную страницу по БЭМ, можно понять место и значение элемента, просто глядя на класс в стилях:
              .main-menu > .main-menu__item > .main-menu__link,
              умно описывать стили элементов, используя уже написанный код"
              .ico.ico_size_16.ico_map
              2) Семантичность. Вам что-то мешает использовать уместные тэги в БЭМ?) Мне, и многим бывшим и нынешним коллегам — нет)
              • 0
                .main-menu > .main-menu__item > .main-menu__link,
                .ico.ico_size_16.ico_map

                Простите, насчёт читабельности не убедили. Смурфовские имена ещё никому читабельности не добавляли.

                Семантика не ограничивается только тегами.
                • +2
                  Чтож, до того как меня на прошлом месте работы не убедили попробовать — я плевался и считал это нечитаемым. Сейчас в 95% случаев с ужасом смотрю на читабельность больших проектов «не по БЭМу», часто их поддержка отнимает необоснованно много времени.
                  • +1
                    Уверяю, если бы все эти 95% были разработаны _теми же людьми_ по БЭМу — вас бы вообще вывернуло наизнанку.
                    • +1
                      Простите, но мне кажется у вас двоих разное представдение о «читабельности» :)
                      • 0
                        Ну, многие, например, говорят, что стили, записанные одной строчкой, много читабельнее, чем блочные.
                        Надеюсь, что только у нас двоих разное представление о читабельности.
                • 0
                  Что вы имеете в виду когда говорите что БЭМ рушит вам семантику кода?
            • 0
              Есть хорошее правило на Хабре: минусуешь — аргументируй.
              • +1
                Нет такого правила.
                • +4
                  Я же говорил. ;]
            • +2
              Главные принципы хорошей вёрстки — это её семантичность, последовательность и читабельность.
              А главные принципы поточной разработки — хорошая поддерживаемость кода, возможность быстрого внесения изменений, простота передачи кода от одного человека другому и быстрый вход нового человека в команду и проект.
              • 0
                Если вы посмотрите внимательно, то все 3 пункта, перечисленных мною, как раз направлены на достижение указанных вами целей.
    • 0
      Названия CSS классов БЭМ весят больше чем HTML теги ))
      Вы можете использовать jeanny для сокращения классов в своём проекте.

      В Яндексе везде используется gzip и он даёт достаточно хорошее сжатие, чтобы не заморачиваться с этим.
  • НЛО прилетело и опубликовало эту надпись здесь
  • +14
    Главная проблема БЭМ в том, что это велосипед. Крутой, сделанный профессионалами но велосипед. То есть продукт, в котором не учтена природа html и css, долгие годы их эволюции.
    • 0
      БЭМ — это не только правила записывания стилей, это инструмент, позволяющий создавать страницы, используя в качестве сущностей — не теги, а БЭМ сущности.
      Например: блок List
      <ul class="list">
          <li class="list__item">Привет</li>
          <li class="list__item">Пока</li>
      </ul>
      

      можно, добавив один модификатор, превратить в:
      
      <table class="list list_type_table">
        <tr>
          <td class="list__item">Привет</td>
          <td class="list__item">Пока</td>
        </tr>
      </table>
      
      • 0
        <table style="list-style-type: circle; border: solid 1px #ffffff"> <tr> <td style="display: table-cell;">Привет</td> <td style="display: table-cell;">Пока</td> </tr> </table>
        Назад в будущее?
        • 0
          вы в моем коде что-то подобное увидели?
          • 0
            Я увидел то, что можно без создания файлов стилей компилить/генерить прямо в разметке правила стилей. И их так же хорошо можно гзипануть за счет повторяющихся фрагментов. И выглядит это практически так же нативно и линейно. И конечно же это плохо. Сама мысль БЭМ может быть и не плоха, но уж очень она напоминает что-то такое, что уже давно проехали ранее, только в другой «одежке», которую я и продемонстрировал в коде комментарием выше.
            • 0
              Напоминает, но тут уже писали, что, к примеру, b-popupa_theme_ffffff не обязательно задаёт только цвет — это просто название темы, в которую входит много чего. Ну и т.д.
            • +1
              в том, что вы увидели, я вижу очередной уровень семантики
              <ul class="menu">
                  ...
              </ul>
              

              о чем говорит этот кусок когда? это меню, возможно, это меню в виде списка

              <ul class="menu menu_layout_horisontal menu_type_dropdown menu_theme_macosx">
                  ...
              </ul>
              

              что можно сказать об этом кусе кода?
              — это меню
              — возможно в виде списка
              — это горизонтальное меню
              — в нем есть дропдауны
              — скорей всего оно похоже, на меню из mac OS x
              мне нравится, когда я могу по 1 строке html кода сказать о блоке так много
              более того, я даже могу вам сказать где на файловой структуре искать стили от каждого из классов, что в разы ускоряет работу с кодом, и не заставляет каждый раз пользоваться поиском

              для меня это тоже было странным, но сейчас я понимаю, что это удобно, и нет ничего плохо в классах — их для этого придумали :)
    • +3
      То есть продукт, в котором не учтена природа html и css, долгие годы их эволюции.
      Поверьте, там учтена природа HTML/CSS и годы их эволюции.

      И учтено так же, что HTML/CSS не предназначены для создания современных web-приложений и современных сайтов.

      Создатели HTML/CSS не предполагали такого их использования и дальнейшее хаотичное развитие этих технологий академиками из W3C (в противоположность практикам) в конце 90x ничего хорошего в долгосрочное переспективе не дало.

      Инициатива WHAT WG по созданию Web Applications 1.0 была хорошей, но опаздавшей на несколько лет и слишком долгой в разработке.

      До создания БЭМ я много верстал, спецификации HTML и CSS были прочитаны мною много раз.

      История создания БЭМ описана статьях в клубе и рассказана мной на Я.Субботнике в Минске. Поверьте, это был не быстрый и не лёгкий путь. Было много проб и ошибок, пока мы не выработали систему, которая позволяет верстать проекты так, чтобы их было легко поддерживать и развивать дальше, не превращая код в кашу.
  • +21
    что бы посмотреть на живом примере залез в первый попавшийся сервис яндекса, в метрику.

    <div class="b-popupa b-popupa__without-padding b-popupa_theme_ffffff b-popupa_direction_down b-popupa_is-bem_yes i-bem b-dropdowna__popup b-dropdowna__menu b-popupa_js_inited">
        ...
    </div>
    


    Это окошко, которое появляется при клике на «Счётчики».

    Мне кажется если именовать классы с умом то БЭМ имеет место быть, цсс «говорящий» получается. Хотя «b-counter-popup» читается проще да и быстрее :)
    • +25
      Это уже какой-то back to inline styles получается.
      • +2
        Не стоит пугаться, прописывается все это не руками, а специальной программой, генерирующей код исходя из заложенной логики.
        • 0
          С тем же успехом программа может inline style="..." генерировать, никто не будет пугаться.
          • 0
            Вы действительно не видите разницы между написанными выше классами и inline style?
            • 0
              Вижу, что inline style эффективнее.
              b-popupa__without-padding вместо paddind:0
              b-popupa_theme_ffffff вместо background:#ffffff

              И только не говорите, что в CSS это будет проще поменять:
              .b-popupa__without-padding { paddind: 5px }
              .b-popupa_theme_ffffff { background: #cccccc }
              • +4
                b-popupa__without-padding вместо paddind:0
                Почему вы думаете, что without-padding это padding: 0? И theme_ffffff вполне может быть с градиентами и фоновыми картинками.

                Отличие класса от inline стиля состоит в том, что ему может соответствовать разный CSS как в пределах разных страниц одного проекта, так и в пределах разных проектов.

                Ну и названия without-padding и theme_ffffff хотя и говорящие, но не самые лучшие.

                «Программировании есть две проблемы — инвалидация кешей и именование переменных» ©
    • +6
      Что-то это не похоже на отделение структуры документа от представления, которое так пропагандируют последнее время. Особенно стиль ffffff.
      • 0
        ffffff — название темы
    • +2
      Мне кажется, что если есть хотя бы теоретическая возможность программно перебрать html/css/js с целью конвертировать вот этот ад в короткие уникальные имена вроде jShx¸ Hjy и т.д. стоит попробовать.
      Кстати, никто не знает подобного софта?
      • 0
        Эта возможность есть, и не теоретическая, а практическая. Google Closure + Soy Templates умеют это по дефолту.
        То что яндекс чудачит таким образом оставляя имена в чистом виде, либо недоработка, либо продукт все еще находится в стадии отладки.
        • 0
          Гляну, спасибо.
        • 0
          То что яндекс чудачит таким образом оставляя имена в чистом виде, либо недоработка, либо продукт все еще находится в стадии отладки.
          Мы минимизировали классы в выдаче поиска: clubs.ya.ru/company/replies.xml?item_no=23106

          Отказались от этого из-за всё большего количества js-кода, в котором классы могут получаться склейкой строк. После минимизации классов они получаются другими и js-код перестаёт работать.

          Чтобы избежать этого, надо всю работу с классами вести через функции, которые скрывают конечные классы, позволяя при этом работать с блоками/элементами/модификаторами.

          В этом случае до минимизации эти функции будут работать с одними классами, а после минимизации — с другими.

          Это понятно как сделать, но руки сделать это ещё не дошли, есть более приоритетные задачи.
      • +3
        Возможность есть. Но измерения показали, что после гзипования разницы между двумя документами с длинными классами и короткими нет. Поэтому мы отказались от идеи такой конвертации.
        • 0
          Ясно, спасибо, что отписались, очень интересовал этот вопрос.
          • +1
            Почитайте эти статьи: clubs.ya.ru/bem/posts.xml?tag=10430536
            Там много всего есть про оптимизацию конечного кода для браузера.
            • 0
              Спасибо, гляну.
    • –2
      У них так дело дойдет до:

      Нет! Без меня!
      • –2
        Вырезало:

        — Если код выше не отобразился, киньте плз cсылку на интсрукцию по вставке HTML кода в комент
  • +6
    Странно у них там все.

    Зачем нужно все это когда HTML со времен основания описывал данные, а CSS настраивал отображение этих данных.

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

    ===

    На самом деле, мне не очень нравятся наработки Яндекса в методологии верстки. Все начинается с использования движка XSL. xsl уж какой-то не очень понятный и не читабельный, может быть наверное поэтому они привыкли к этому и им такие громоздкие структуры не кажутся проблемой, но не мне.
    • +1
      XSL ломает взгляды многих, кто никогда не сталкивался с декларативными языками программирования, а только с такими, где выполнение команд идет линейно.

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

      А теперь представьте тоннель. Например, тоннель в пещере. Вам надо пройти по нему до определенного места в пещере. У вас есть веревка, примерный маршрут движения. Вы идете по ориентирам, на дороге могут встречаться развилки, приходится выбирать, куда двигаться. В итоге вы или доходите до нужного места или нет, возвращаясь и выбирая другой путь.

      Разница улавливается?

      В случае с XSL, как наиболее близкому к синтаксису самого HTML, мне видится гораздо более прозрачная работа с преобразованием входных данных, чем в шаблонизаторах другого типа.
  • НЛО прилетело и опубликовало эту надпись здесь
    • +3
      А завтра понадобилось добавить иконку, и <a> теперь не в <li>, а в <span>, чтобы не подчёркивались пробелы. Ваш CSS сломался. Или добавился пункт, который не ссылка <a>, а псевдо-ссылка. Опять сломано. Вы получаете удовольствие от мазохизма?
      • +6
        Что значит «сломался»? Вы меняете часть работающей системы, и ожидаете, что все будет работать также, как и прежде? БЭМ может гарантировать это со 100% уверенностью? Нет? К чему тогда весь этот огород из классов?

        Опять же — как часто вы меняете разметку в продакшене? Как показывает мой опыт, если даже такие изменения и делаются, то они не ограничиваются заменой тегов или перемещением их по дереву — часто меняется вид, что само собой подразумевает правку стилей. И тут БЭМ уже не работает.

        Ну и да, как уже не раз было отмечено, SASS/LESS/Stylus позволяют минимизировать любые «мазохизмы», на более высоком уровне.
        • +2
          Имея модульную методологию, вам достаточно использовать тот же класс на новом элементе. А вот не используя, вам придётся перевёрстывать.
          • НЛО прилетело и опубликовало эту надпись здесь
            • +2
              Ага, а логотип и шапка могут быть только одни. А потом появляется страница настроек, где меняется скин, и там —о боже! — появляется вторые! Или появляется элемент подсказки. Или появляется ещё что-то такое же, но с нюансами.

              Первое правило верстальщика: если вам говорят, что будет так и только так, а уж тем более если вы так сами подумали, очень скоро может оказаться, что это совсем не так.
              • НЛО прилетело и опубликовало эту надпись здесь
                • +3
                  Вы когда-нибудь работали в серьёзных проектах? Вас там не будут спрашивать, хотите вы это поддерживать или нет, а просто попросят это сделать.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • +4
                      Методология это одно, а организация файлов и прочего это другое. Мне не нравится, как сделана организация процесса в Яндексе — сильно перемудрили, но ничто не мешает использовать ту же методологию. А методологию стоит использовать практически с любым случаем сложнее простенькой страницы, иначе начинают сказываться недостатки её отсутствия, и увеличиваются затраты времени.
                    • 0
                      У них там и организация файлов проекта, и представление блоков в JSON/XML, из которого потом автоматом генерируется HTML, и привязка к жаваскрипту, и даже инструменты для работы с этим.
                      Почитайте историю развития БЭМ: clubs.ya.ru/bem/replies.xml?item_no=1398

                      Ещё до автоматической генерации HTML и привязки к JS мы использовали БЭМ (только тогда не называли это так, а называли независимыми блоками) и верстали это руками.
                • 0
                  Да ну вы же должны понимать, что элементы с такими классами вроде приведённого выше яндексковского нельзя верстать и поддерживать руками и никто в здравом уме этим заниматься не будет.
                  И верстали, и поддерживали. От того оно всё развивалось и совершенствовалось.
        • 0
          Вы меняете часть работающей системы, и ожидаете, что все будет работать также, как и прежде?
          Да, именно так.
      • +1
        Иконку без проблем можно добавить фоном к ссылке. С паддингом, разумеется.
        • 0
          Это если у вас не спрайт.
          • 0
            Это если иконки в спрайте у вас не «столбиком». :)
            • 0
              Столбик увеличивает как размер самого спрайта, так и потребление памяти.
              • 0
                Хм, если это и так, то разница должна быть совершенно незначительной. Загуглить что-то не получается, не поделитесь пруфом?
                • 0
                  Под рукой ссылки нет, было где-то описание, что чем больше площадь картинки, тем больше потребление памяти. Плюс об этом рассказывали на Яндекс.Субботнике, где в почте скорость работы интерфейса важнее.
        • 0
          Расположить ссылку в пяти пикселях справа вам получиться далеко не во всех браузерах.
    • 0
      ">" не очень рекомендуют использовать. Там что-то спроизводительностью у браузера.
      • 0
        Откуда такая инфа?
        • 0
          Child and adjacent selectors are inefficient because…
          developers.google.com/speed/docs/best-practices/rendering?hl=ru
        • 0
          Переводя ссылку выше, детские и соседние селекторы неэффективны, потому что браузер должен обработать каждый указанный в селекторе узел. И он должен это сделать для каждого элемента, указанного с самого права. Хотя они неэффективны, хуже только контекстные селекторы, которые пишутся через пробелы.
        • 0
          Про проблему скорости селекторов можно почитать тут: clubs.ya.ru/bem/replies.xml?item_no=338
    • 0
      Нет, корректно будет так:
      .nav__item {}
      .nav __item .link {}
      • 0
        Это тоже не по БЭМ — вложенные классы… По БЭМ скорее так:

        .nav{}
        .nav__item {} 
        .nav__item-link {}
        
        • 0
          Ну а в чём проблема? Вот CSS со случайной странички яндекса:
          .b-mail-domik .b-hint-input { /*… */ }

          По БЭМ нормально:
          .main-menu — блок
          .main-menu__item — элемент блока
          .ico_size_16 — модификатор для блока

          двойную вложенность в БЭМ я не встречал
          • 0
            Просто у Вас там пробелы в селекторах, я про это…
          • 0
            .b-mail-domik .b-hint-input — такое может использоваться, когда блоку .b-mail-domik надо переопределить внутри себя блок .b-hint-input
        • 0
          Не хочу вас расстраивать, но это тоже не БЭМ.
          БЭМ выглядел бы так:

          .nav {}
          .nav__item {} 
          .nav__item__link {}
          
          • 0
            По-моему там было что-то про один блок и элемент в классе, но несколько модификаторов (если мне это не приснилось).
            • 0
              Явного запрета на иерархию в именовании элементов блока в их доках я что-то не нашел, к тому же сами яндексоиды на почте верстают именно так.

              Да и с точки зрения логики это, по-моему, правильней, так как link — это по сути элемент, вложенный в другой элемент и не имеющий смысла вне родительского item'а. Если же link такой универсальный и существует потенциальная возможность его дальнейшего использования в другом месте, то он должен быть вынесен отдельно в качестве блока.

              Но в любом случае, даже если ребята из яндекса имели ввиду то, о чем вы говорите — это все малозначительные нюансы и разные команды разработчиков могут с легкостью принимать свои откорректированные условия именования, с которыми им будет удобней работать на том или ином проекте. Главное — придерживаться одного стиля. Основополагающий же тезис методологии о независимости блоков от этого никак не страдает.

              К примеру, у нас на проекте мы с коллегами отказались от всяческих предлагаемых яндексом префиксов, но добавили свой — префикс «w-», который мы добавляем к элементам-оберткам (так называемые wrappers, отсюда и название префикса). Таким образом мы отделяем вспомогательные обертки от участия в иерархии при именовании, о которой я писал выше. Вот типовой пример нашего кода:

              <div class="news">
              	<div class="news__tabs">
              		<div class="news__tabs__item">
              	</div>
              	<div class="news__list">
              		<div class="news__list__item">…</div>
              		<div class="news__list__item news__list__item_hiddable">…</div>
              		<div class="news__list__item news__list__item_hiddable">…</div>
              		<div class="w-news__list__item_project">
              			<div class="news__list__item">…</div>
              			<div class="news__list__item">…</div>
              			<div class="news__list__item">…</div>
              		</div>
              	</div>
              </div>
              

              .news {}
              	.news__tabs {}
              		.news__tabs__item {}
              	.news__list {}
              		.news__list__item {}
              			.news__list__item_hiddable {}
              		.w-news__list__item_project {}
              


              Для нас в такой записи все прозрачно и очевидно, по стилям сразу видна вся структура блока и видно что и от чего зависит внутри него.
              • +1
                Ну в этом есть смысл…
              • 0
                news__list__item_hiddable — вот это действительно ад
                • 0
                  Ну не намного хуже .news .list .item.hiddable просто без пробелов…
                • 0
                  В чем по-вашему заключается адовость? И как бы вы именовали такой пример?
                  • 0
                    news__list-item_type_hiddeable

                    1. двойное подчеркивание отделяет элемент блока
                    2. одинарное — модификаторы элемента и их значения.
                    3. пробелы в именах заменяются на тире

                    мне так больше нравится :)
                    • 0
                      Я, пожалуй, воздержусь от спора о фломастерах, а попробую описать чем лично меня не устраивает приведенный вами тип записи с точки зрения моей логики:

                      1. Вы в имени элемента так или иначе используете ту же самую иерархию именования, что я описал выше, только в качестве разделителя пишете абсолютно нелогичный с моей точки зрения символ дефиса.
                      «list» — это элемент? Да.
                      «item» — это элемент? Да.
                      Элементы по БЭМ отделяются так — "__элемент"? Да.
                      Так при чем здесь тогда дефис? И, интересно, как бы вы написали такое — «news__list__item__link__image»?

                      2. Именование модификаторов как "_ключ_значение", на мой взгляд, излишне. На практике для нормального понимания абсолютно всегда достаточно написать только "_значение". Или кому-то в строке "*_disabled *_hidden *_big" будет непонятно, что "_disabled" — это о состоянии, "_hidden" — о видимости, а "_big" о размерах? Зачем писать лишние "_state", "_visibility" и "_size", когда все и без них очевидно?
                      • 0
                        Ну в его записи не list элемент и item элемент а list-item элемент, как и положено… К тому же если иерархия плоская, а стили независимы — совершенно не нужно описывать оную иерархию в имени класса. Как я это вижу…
                        • 0
                          Я прекрасно понимаю что имеется ввиду в записи Beyondtheclouds. Я же пытаюсь абстрагироваться от документации и следовать логике.
                          И, думаю, бессмысленно доказывать, что белое — это белое, а в этой абстрактной разметке:

                          <div class="news">
                              <div class="list">
                                  <div class="item">…</div>
                              </div>
                          </div>
                          

                          … news — блок, list — элемент блока, а item — элемент блока, вложенный в другой элемент блока.

                          К тому же если иерархия плоская, а стили независимы — …

                          Стили внутри блока не могут быть независимы. В большей или меньше степени, но они обязательно зависят от того, что рядом, во что обернуты и что внутри. А если элемент независим, то это уже блок.
                          • 0
                            Харисов не раз говорил о том что элемент может быть внутри блока на любом уровне вложенности.
                            b-news
                            b-news__list
                            b-news__item

                            <div class="b-news">
                                <div class="b-news__list">
                                   <div class="b-news__item">...</div>
                                   <div class="b-news__item">...</div>
                                   <div class="b-news__item">
                                       <div class="b-news__list">
                                             <div class="b-news__item">...</div>
                                       </div>
                                   </div>
                                </div>
                            </div>
                            
                            • 0
                              Да я уже понял, что «чисто по БЭМ'овски, как Виталя прописал» все именно так, как вы говорите. Даже покаялся чуть ниже в комментах.
                              Теперь же просто высказываю точку зрения о том, что оригинальное БЭМ-именование, на мой взгляд, нелогичное и трудное для восприятия, и объясняю как и почему, опять же на мой взгляд, было бы логичней и понятней.
                              • 0
                                оно логичное, если помнить о том, что это все папки на файловой системе
                                github.com/bem/bem-bl/tree/master/blocks-desktop/b-link
                                • +1
                                  Согласен. Если брать всю методику разработки в целом, то, конечно, учитывать иерархию внутри элементов и делать многоуровневые вложенности папок в файловой системе абсолютно излишне и было бы полнейшим маразмом.

                                  Если же брать только метод именования (ну и, конечно же, независимость блоков), то в отрыве от вашего инструментария и системы разбивки всего внутри блока на папки — метод именования становится нелогичным. А, как мне кажется, в большинстве случаев верстальщики с небольших проектов как раз заимствуют только именование.
                          • 0
                            news — блок, list — элемент блока, а item — элемент блока, вложенный в другой элемент блока.
                            Да, элементы вкладываются один в другой при использовании, но при описании этих элементов проще использовать плоский список, не вкладывая их в коде и на файловой системе один в другой. Это позволяет не менять код, когда между list и item появится ещё один элемент.
                      • 0
                        Вы в имени элемента так или иначе используете ту же самую иерархию именования, что я описал выше, только в качестве разделителя пишете абсолютно нелогичный с моей точки зрения символ дефиса.
                        Дефис отделяет слова в составных именах, вне зависимости от того, блок это, элемент или модификатор.

                        Как-то так: long-long-block-name__long-element-name_mod-name_value

                        Так при чем здесь тогда дефис? И, интересно, как бы вы написали такое — «news__list__item__link__image»?


                        news__list
                        news__item
                        news__link
                        news__image

                        Если хочется явно указать принадлежность item к list'у — news__list-item. Это по-прежнему будут два разных элемента, но их родственность определяется близкими именами.
                      • 0
                        Именование модификаторов как "_ключ_значение", на мой взгляд, излишне. На практике для нормального понимания абсолютно всегда достаточно написать только "_значение". Или кому-то в строке "*_disabled *_hidden *_big" будет непонятно, что "_disabled" — это о состоянии, "_hidden" — о видимости, а "_big" о размерах? Зачем писать лишние "_state", "_visibility" и "_size", когда все и без них очевидно?
                        Мы тоже так думали, пока не начали писать много JS, который работает с модификаторами и меняет их значения.

                        Вам надо изменить модификатор size со значения big на small — вы ищете модификатор по его типу, а не по значению. Типы модификаторов в пределах одного блока/элемента уникальны, а вот их значения могут совпадать.
                    • 0
                      Да, у вас написано правильно. Мы именно так и делаем.
              • +1
                К примеру, у нас на проекте мы с коллегами отказались от всяческих предлагаемых яндексом префиксов, но добавили свой — префикс «w-», который мы добавляем к элементам-оберткам (так называемые wrappers, отсюда и название префикса).
                У нас был префикс h- (holster) ровно для этого, но потом мы от него отказались. Вообще отказались от всех префиксов, кроме b- и i- и то, используем их сейчас из-за большого количества кода с ними. Нельзя просто так взять и отказаться от префиксов :)

                Если бы я сейчас проектировал всё с нуля, я бы не использовал префиксы.
          • 0
            Вот тут вы явно ошибаетесь: «item?link» — имя элемента. А вы внутри имени ставите разделитель «блок-элемент». Пример qnub верен.
            • 0
              А вы внутри имени ставите разделитель «блок-элемент».

              Я ставлю разделитель "__элемент-блока", вложенный в "__другой-элемент-блока", так как в данном случае они неотделимы. Чуть подробней описал в комменте выше.
              • 0
                Я ставлю разделитель "__элемент-блока", вложенный в "__другой-элемент-блока", так как в данном случае они неотделимы.
                В том-то и дело, что отделимы и в любой момент между ними может встать другой элемент. Лучше делать набор независимых, не цепляющихся друг за друга элементов и делать их них финальный сендвич только в HTML, а не при написании кода.
          • 0
            .nav — блок nav
            .nav__item — элемент item блока nav
            .nav__item__link — элемент link элемента item блока nav
            последнее не по БЭМ, т.к. считается, что элементы — это отдельные сущности и у них нет CSS представления вложенности друг в друга, правльней или .nav__link или .nav__item-link
            • 0
              С категоричностью первого высказывания, конечно, погорячился, каюсь.
              Просто мне БЭМ представлялся более логичным, универсальным и понятным, чем он есть на самом деле. Раньше удивлялся тому, что многим он непонятен и монструозен для восприятия. Теперь же понимаю отчего это происходит.

              Так как, глядя на вашу почту, я был уверен, что в БЭМ именование происходит именно так, как уже описывал выше, я неоднократно давал своим друзьям начинающим верстальщикам ссылку на bem.info (хотя сам года 2-3 ничего не читал про БЭМ) и у всех без исключения после прочтения гайдов метод именования вызывал затруднения. После того же, как я объяснял все со своей колокольни, опять же все без исключения говорили «ааа, теперь все понятно, так бы сразу и сказал».

              Замечу, что я говорю только о методе именования. Основополагающий же принцип БЭМ'а о независимости блоков бесспорен.
              • 0
                метод именования:
                — имена пишутся через дефис, block, block-1, elem-name, mod-name
                — элементы — два нижних подчеркивания: block__elem, block-1__elem-name
                — модификатор имя нижнее подчеркивание значение: block_size_xl, block__elem_elem-size_xxl,
          • 0
            Если вы говорите о том, какие классы используют в Яндексе, то это не так: схема именования элемента не зависит от его вложенности в другие элементы.
            Если вы говорите о БЭМ в целом, то это тоже не верно. БЭМ как методология не регламентирует именование классов, оставляя это за конкретной реализацией.
            • 0
              Если вы говорите о том, какие классы используют в Яндексе, то это не так: схема именования элемента не зависит от его вложенности в другие элементы.

              Я говорил о верстке Яндекс.Почты и, как мне думалось на тот момент, об именовании по БЭМ'у в целом. Выше я уже неоднократно признавал, что был не прав на этот счет.

              Если вы говорите о БЭМ в целом, то это тоже не верно. БЭМ как методология не регламентирует именование классов, оставляя это за конкретной реализацией.

              Не о БЭМ в целом, а только о вашем, так сказать, дефолтном методе именования по БЭМ'у.
  • +6
    На текущей работе есть требование верстать по методике БЭМ, так вот плюсы вполне видны, но время разработки увеличивается в разы и читабельность html кода падает катастрофически.
    Мой личный взгляд на этот вопрос — нужно выделять самостоятельные модули (к примеру кнопки, иконки, другие подобные вещи), но не болеть БЭМом головного мозга.
    На моём очень проекте переиспользуется процентов 10 кода, при этом на создание остальных стилей убивается огромное количество времени. По ходу разработки видны куски, которые будут переиспользоваться, а если их сразу и не заметил, то всегда можно к ним вернуться и заменить, при этом потратив намного меньше времени.
    Вёрстка без наследования и привязки к тэгам — это шаг назад, я это вижу на собственной практике.
    • 0
      но время разработки увеличивается в разы и читабельность html кода падает катастрофически
      Можете описать, как у вас организован процесс разработки, что время разработки увеличивается в разы? Может быть смогу что-то подсказать для ускорения работы.
  • 0
    Вот тут я отчётливо ощутил все проблемы классических стилей. В итоге я просто стал заменять их на БЭМ по мере необходимости.

    Представьте реакцию верстальщика, который придет работать в проект после вас, ведь вполне возможно, что ему будет нравиться какой-то третий стиль написания селекторов.
    Я бы на вашем месте все-таки придерживался заданного стиля.
    • +1
      Как показывает практика, после применения такой методологии что-то делать в разы проще, чем иметь проблемы с наследованием, специфичностью и тому подобные.
    • 0
      Вертальщик пусть учится. Он может и своё именование любить, но за одно изолирование блоков уже в ножки полонится, коли не дурак.
  • +10
    Несколько лет уже верстаю с некоторыми идеями БЭМ. Имхо тот БЭМ, которые предлагается сейчас, оправдан только для больших проектов, в которых производятся постоянные изменения. Яндекс например =) У них же практически все сервисы на одинаковых блоках — для них это реально ускорение разработки и поддержки. Для мелких и средних проектов разработка в строгом в соответствии с БЭМ — только увеличение сроков, а пользы гораздо меньше. В таких проектах нет смысла везде использовать, например, абсолютно независимые блоки.

    В своей верстке использую следующие правила:
    1) именование только классами.
    2) блоки, задающие структуру страницы, именовать с префиксом l- (деление на колонки к примеру)
    3) логически выделенные блоки (например, меню, список новостей, пагинация и тп) именовать классом с префиксом b-, а внутри этих блоков именовать как угодно
    4) блоки, которые могут использоваться внутри других блоков, делать абсолютно независимыми (к примеру вывод какой-н. информации, который используется в различных блоках)
    5) Модификаторы класса указываю через дефис (поэтому для названия блока использую стиль camelCase).

    В таком случае не теряется скорость верстки из-за оч. длинных классов и их увелечения, но при этом мы получаем лёгкую поддержку верстки и безпроблемное написание новых блоков.
  • +6
    Яндекс и его верстальщики работают с горой сервисов, как следствие им требуется безболезненно тягать 100500 блоков из одного проекта в другой с минимальными напрягами (желательно — копипастой). Если вы не содержите сопоставимый по количеству парк сервисов и сопоставимый же по количеству штат верстальщиков, тестеров и т.д. — БЭМ подойдет слабо.
    В нашей компании его тоже думали внедрить, но посмотрев на эти неудобочитаемые имена и поняв, что искать отлаживать в этой энтропийной каше придется уже мне — обматюгал благое начинание во славу прогресса и потребовал нормальные имена, по которым можно понять, что это за элемент такой.
    • 0
      Яндекс и его верстальщики работают с горой сервисов, как следствие им требуется безболезненно тягать 100500 блоков из одного проекта в другой с минимальными напрягами (желательно — копипастой).
      Copypasters will burn in Hell.

      Копипастить код с проекта на проект — обрекать себя на муки обновления кода при изменении HTML. Мы выделяем общие блоки в библиотеку и подключаем её на все проекты.
      • 0
        Вполне допускаю, что руками в яндексе тоже тягают не так много — по крайней мере xslt позволяет это делать, а для сохранения целостности css у них БЭМ и есть. Другое дело, что это в любом случае выливается в необходимость тягать какие-то куски, которые не будут меняться. И чем больше они не будут меняться — тем проще этим зверинцем управлять.
  • +7
    В яндексе верстка руками не пишется. Она генерируется шаблонами и препроцессорами. При таком подходе ты в голый html не лезешь даже. Я давно как-то писал об этом: pokrovskii.com/obektno-orientirovannaya-verstka/ сейчас делаю немного по другому. Если интерес есть по этому вопросу и наберется много просьб, могу написать материал сразу на хабр.
    • +1
      Давайте!
  • +1
    Первым делом, начиная описывать преимущества БЭМ, стоит описать размер проекта, его длительность (сколько и как часто надо будет вносить правки), описать размер команды. БЭМ — решение не универсальное, и как всякий инструмент хорош в определенном круге задач.

    А то довольные БЭМ-мом пишут с восторгом одно, а читающие представляют себе каждый свое.
    • 0
      На больших проектах с большой (возможно, распределённой) командой, на своём опыте скажу что БЭМ + жёсткий стандарт кода — спасение для верстальщика.
  • +2
    Статье явно не хватает примеров с псевдоклассами, аля .megalink:hover.
    • 0
      Не очень понял. Там вроде бы всё классически — просто добавляется псевдокласс к классу элемента, собственно, как Вы и написали. Может я чего-то не понимаю, но новых подводных камней я с этим не встречал…
      • 0
        Не совсем, вместо псевдоклассов лучше использовать (если возможно) JS, который будет навешивать классы виде .element__hover или типа того.
        • 0
          Не совсем, вместо псевдоклассов лучше использовать (если возможно) JS, который будет навешивать классы виде .element__hover или типа того.
          Зависит от вёрстки и того, хочется ли менять программно hover, например.

          Хотя соглашусь, что управлять модификаторами из скрипта во многих случаях удобнее, чем полагаться на механизм браузера.

          Например, если надо выставить состояние hover не при наведении мышью, а при фокусе с клавиатуры или ещё как.
  • +2
    Некоторые предпосылки, на которых основывается БЭМ, вполне разумны и правильны. Я сам прошел путь от вложенных и сильно зависимых классов (до 4-5 уровней доходило), к более плоской и независимой структуре.
    Вложенные классы можно сделать очень логичными и читаемыми в сиюминутно имеющемся коде/дизайне. Но модифицировать их действительно фиговато.

    Однако тут, имхо, верная в принципе идея доведена до абсурда. Нужно что-то среднее.
  • +7
    Перепись тех, кто выпускает по десять сайтов в месяц, и тех, кто поддрживает проекты годами.
  • +1
    А почему нельзя в пределах одного блока верстаться? Если все стили относительно его корня, например .search_bar > ..., то блок точно также можно будет двигать и верстать независимо от остальной страницы. Или я не уловил чего-то?
    • +1
      Если у вас внутри блока есть то, что завтра захотят использовать внутри другого блока вам придется копировать стили.
      • 0
        Верно, получается заранее неизвестно, что именно самый маленький блок, и потому проще разбить вплоть до элементов.
        С другой стороны если что-нибудь из мира less:

        .search_bar {
        bla bla bla
        a {
        color: blue;
        }
        }

        И здесь можно легко копипейстнуть 'a'.
        • 0
          Ну, я не знаю как там у них все устроено. Представьте: пишем парсер, который разбирает css буквально на словарь стилей, где ключ имя класса, а значение сам класс. Затем он пробегает по хтмл и разбирает атрибут класс у элементов, выдирает из них названия, возвращается к нашему словарю и вот вуаля: собирает пачку стилей только из того, что используется.

          Т.е. может получиться так, что вам достаточно описать хтмл, а файл со стилями соберется сам из базы. При таком подходе вот эта бяка в названиях вполне оправдана.
        • 0
          А потом в этот блок вы вставляете ещё что-то, где тоже есть ссылка, и получаете проблемы с наследованием стилей, которые совсем не подразумевались.
          • 0
            Какие же тут проблемы? Назначили этой ссылке свой класс и раскрасили как надо.
            • +5
              Нее, не так.

              Вставили что-то в старый блок. Задеплоили. QA вернул — белый текст на белом фоне! Прописали класс ссылке. Перебивается. Нашли, добавили веса именами родителей. Не хватило. Импортант. Уже вверху есть. Какой дебил… А, это я полгода назад — фичу сдавали. Попробовал убрать этот верхний импортант — ого, он вообще в инлйне. Я что через телефон фиксил, что ли…

              Смеркалось.
              • 0
                Ага, в конечном итоге в такое и выливается.
              • 0
                Вставили что-то в старый блок. Задеплоили. QA вернул — белый текст на белом фоне! Прописали класс ссылке. Перебивается. Нашли, добавили веса именами родителей. Не хватило. Импортант. Уже вверху есть. Какой дебил… А, это я полгода назад — фичу сдавали. Попробовал убрать этот верхний импортант — ого, он вообще в инлйне. Я что через телефон фиксил, что ли…
                Браво!
        • 0
          Или использовать SASS/SCSS и extend. И читаемость сохраняем и модульность — получите, распишитесь.
    • 0
      Не очень понятно почему лучше писать .search_bar > .ещё_стиль чем .search-bar__элемент?
    • 0
      Если вёрстка делается один раз и больше никогда не меняется — можно верстать и через .search_bar >…

      Но если в любой момент структура блока может измениться (в один блок сложиться другой; добавятся дополнительные обёртки или наоборот уберутся; etc), то вам придётся каждый раз переписывать эти дочерние селекторы, которые сильно завязаны на конечную структуру HTML.

      БЭМ позволяет отвязать CSS от структуры HTML и управлять ими независимо. Это с одной стороны даёт гибкость в поддержке, а с другой стороны усложняет как HTML, так и CSS. За всё надо платить.
  • –3
    Как это после конференции Яндекса, у их представителей спросили — «А вы используете то, про что вы нам рассказывали?», они ответили — «Нет», из-за какой-то внутренней специфики. Больше этой компании я не верю.
    • 0
      бредовый коммент. На их проекты посмотрите — там БЭМ.
      • 0
        Пример выше посмотрите, как у них бэм реализован. Бредовый не коммент, а большинство решений яндекса.
      • 0
        К тому же не о конкретно этом примере, а вообще. Чуть позже найду пруф. Так что любые статьи, конференции яндекса у меня вызывают двоякие чувства.
    • –2
      Оказывается много фанатиков яндекса ну-ну.
  • +2
    Фуф, чем дальше, тем больше БЭМ напоминает попытку въехать в историю разработки ПО и интерфейсов на какой-то мутной и кривой кобыле.


    Счастливы без БЭМ

    Хорошо, что текущим потребностям мира front-end разработчиков какая то мутная концепция блоков, состоящая из потрохов производственных процессов отдельно взятой компании, нежизнеспособных за ее стенами отвечает меньше всего.

    В качестве примера реального вклада в front-end разработку, twitter не так давно выкатил bootstrap и он моментально решил огромное количество проблем для огромного количества проектов, предаставив каркас-конструктор стилей, классов, конвенций по структуре тегов для элементов и т.д. Они войдут в историю, а какой-то БЭМ — нет.

    Пытаясь весь этот цирк форсировать силами своих специалистов на различных конференциях яндекс заставляет выглядеть их просто глупо, искренне сочувствую.

    И прошу меня извинить за резкий тон, не люблю когда что-то настолько узколобо навязывают, чем бы это не было.
    • +1
      А где они навязывают?
    • +3
      На самом деле данная методология призвана решить не просто проблемы с каскадностью css. Данная методология шаг к созданию универсального инструмента написания клиентского приложения по принципу RAD. Когда вы имеете полноценный инструмент быстрого создания приложения с необходимым функционалом, минимум времени внесения правок в эти приложения без погружения в логику. Главное — что вы быстро сможете поменять в таком редакторе расположение элементов / стили / поведение элементов — при этом вам все равно, какой код сгенерируется, главное, что он будет работать.
      Это единственное новое, что я вынес из докладов про БЭМ, что мне нравится. Потому что за то время, пока существует html и css, многие настолько превратились в фанатов этих аббревиатур, что забыли самое главное — пользователя не интересует, насколько красив код в редакторе, ему нужен быстрый, удобный, работающий сайт (веб-приложение), все остальное его не интересует.
      Да, я с вами согласен, такие инструменты как bootstrap и многие другие, так называемые, фреймворки — также повышают удобство создания страниц, но по сути — это всего лишь один из путей к быстрой разработке. Но не единственный.
      С другой стороны, есть огромный круг задач, где не обойтись использованием каких-то определенных концепций / фреймворков и тп. и приходится подстраиваться под логику бэкэнда, а там, поверьте, бардак не меньший.
      Тут же ребята хотят решить не просто проблему разработки фронтэнда в отрыве от бэкэнда, а в совокупности.
      Вернемся к вашему примеру с bootstrap. Да, наверное этот фреймворк замечателен, но я бы не стал использовать его в своих проектах. Во-первых, мне нет смысла брать некий универсальный css, а затем допиливать его стили под себя — для начала надо потратить время и разобраться, а что же за стили вообще там есть, потом нужно понять, а нужны ли мне эти стили, и только потом я пишу код. Без bootstrap я сразу пишу нужный мне код (часто делается копипаста кода из предыдущих проектов). Все-таки не стоит с молоду приучать себя к готовым продуктам. Хороший верстальщик обязан разобраться во всем сам. Остальное — вопрос потраченного времени.
      • 0
        >Все-таки не стоит с молоду приучать себя к готовым продуктам. Хороший верстальщик обязан разобраться во всем сам. Остальное — вопрос потраченного времени.

        Я обычно для своих проектов сам делаю верстку, хотя ни разу не виртуоз less/css, но, допустим, у браузеров есть вшитые default стили. Обычно это полный отстой, подлежащий обнулению. И это первое с чем сталкивается кто-то с молоду. Мне вот хочется чтобы этот пережиток просто исчез и никогда больше не упоминал о себе. Потом новичок сталкивается с html селекторами, допустим, что есть и , он сидит, чешет репу и не очень понимает как именно правильно, потом он сталкивается с тегами представления и опять в задумчивости над .

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

        Человек не будет совершать ошибки, если у него нет выбора, bootstrap своей структурой классов и их привязкой кроме прочего навязывает очень корректный html, например нормально прописывать бирки к полю в форме (я до сих пор повсюду вижу формы, где поля и подписи к ним сделаны двухколоночной таблицей) или caption к таблице. В итоге, новичок, который просто полез в его мануал впитывает хорошие практики, и только после этого, на мой взгляд, стоит вникать в детали шестеренок.

        >С другой стороны, есть огромный круг задач, где не обойтись использованием каких-то определенных концепций / фреймворков и тп. и приходится подстраиваться под логику бэкэнда, а там, поверьте, бардак не меньший.

        Хороший вариант логики бэкэнда это он вообще не в курсе про html и css, и предоставляет удобный api, который в свою очередь использует front-end на js, который занимается шаблонизацией и всем прочим. Негоже жаловаться на бардак если область его возникновения не была вовремя изолирована. Если очень нужно выдавать именно html с серверной стороны, то можно задуматься о службе шаблонизации между бэком и выдачей, которая в случае невозможности этого процесса на клиенте возьмет ее на себя. К этому все идет и это, с точки зрения архитектуры, наиболее внятная схема.

        Идея сплавить front-end и back-end лучше всего была выражена в gwt и судьба его при всех плюсах и продуманности сложилась просто никак.
        • 0
          Ох прошу прощения, забыл теги запихнуть в code
      • 0
        >Все-таки не стоит с молоду приучать себя к готовым продуктам. Хороший верстальщик обязан разобраться во всем сам. Остальное — вопрос потраченного времени.

        Я обычно для своих проектов сам делаю верстку, хотя ни разу не виртуоз less/css, но, допустим, у браузеров есть вшитые default стили. Обычно это полный отстой, подлежащий обнулению. И это первое с чем сталкивается кто-то с молоду. Мне вот хочется чтобы этот пережиток просто исчез и никогда больше не упоминал о себе. Потом новичок сталкивается с html селекторами, допустим, что есть <button> и <input type="submit">, он сидит, чешет репу и не очень понимает как именно правильно, потом он сталкивается с тегами представления и опять в задумчивости над <b> <strong> <span class="strong">.

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

        Человек не будет совершать ошибки, если у него нет выбора, bootstrap своей структурой классов и их привязкой кроме прочего навязывает очень корректный html, например нормально прописывать бирки к полю в форме (я до сих пор повсюду вижу формы, где поля и подписи к ним сделаны двухколоночной таблицей) или caption к таблице. В итоге, новичок, который просто полез в его мануал впитывает хорошие практики, и только после этого, на мой взгляд, стоит вникать в детали шестеренок.

        >С другой стороны, есть огромный круг задач, где не обойтись использованием каких-то определенных концепций / фреймворков и тп. и приходится подстраиваться под логику бэкэнда, а там, поверьте, бардак не меньший.

        Хороший вариант логики бэкэнда это он вообще не в курсе про html и css, и предоставляет удобный api, который в свою очередь использует front-end на js, который занимается шаблонизацией и всем прочим. Негоже жаловаться на бардак если область его возникновения не была вовремя изолирована. Если очень нужно выдавать именно html с серверной стороны, то можно задуматься о службе шаблонизации между бэком и выдачей, которая в случае невозможности этого процесса на клиенте возьмет ее на себя. К этому все идет и это, с точки зрения архитектуры, наиболее внятная схема.

        Идея сплавить front-end и back-end лучше всего была выражена в gwt и судьба его при всех плюсах и продуманности сложилась просто никак.
    • +1
      Кстати Вы обратили внимание, что стили кнопок в том же bootstrap повешены не на тег input, а на класс .btn? Я даже сначала удивился и возмутился и понаписал своих «правильных» стилей (т.е. добавил через запятую input[type=«submit»] и т.д.). Но потом я понял, что это было ошибкой. В итоге и ребята из твиттера и ребята из яндекса делают одно и тоже — избавляются от селекторов не классов… Кто правее — поживём увидим. Ни кто же не навязывает (люди просто делятся опытом), если Вас мои примеры не убеждают — ну значит это Вам не подходит, но тоже не означает, что это автоматически не подходит всем.
      • 0
        Так и я говорю, что bootstrap представлят очень хороший каркас по классам, минимально привязанный к селекторам, не нужно изобретать велосипед.
      • 0
        Ну вообще, вешая стили на какой-то тег, сразу стоит понимать, чем это может обернуться. Вот я, например, раньше вешал бордер на input по молодости.
        )

        Классы в данном случае дают возможность сосуществования на странице, например, различных кнопочек без необходимости лепить переопределяющие стили в каждый новый их вид. Ну кнопочки это ладно. Ад начинается, когда джаваскриптеры пытаются одновременно побыть и верстальщиками и дизайнерами, намертво внедряя презентационные стили в свои скрипты. Иногда приходится сталкиваться с такими поделиями. Хорошо, что в это время никого нет рядом)
    • 0
      А сам Яндекс, Рамблер, Хедхантер, Yota, lj, лента.ру?
      + Google так или иначе использует близкую концепцию.
      • 0
        Сама концепция достаточно размыта и в основном предлагает достаточно очевидных вещи типа изолированной модульности с учетом контекста и можно долго перечислять тех, кто использует схожие подходы.
        • +1
          Тогда я не понял вашу позицию. Всем можно иметь свою реализацию «размытых концепций», а яндексу нельзя?
        • 0
          Сама концепция достаточно размыта
          Вы, очевидно, саму концепцию не читали даже, раз говорите о её размытости.
    • +1
      У вас там в картинке Яху и Фейсбук. Какая ирония.

      Есть такая девушка — Николь Салливан. У нее есть некий OOCSS — на 50% где-то с идологией БЭМа совпадает, как минимум. Так вот как раз для фейсбука и яху она эту штуку и применила.
    • +1
      Пытаясь весь этот цирк форсировать силами своих специалистов на различных конференциях яндекс заставляет выглядеть их просто глупо, искренне сочувствую.
      БЭМ в Яндексе занимается группа энтузиастов, которые его развивают и по мере своих сил распространяют вне Яндекса.

      В Яндексе никто никого не заставляет выступать на конференциях, наоборот сложно оторвать людей от работы и уговорить сделать доклад, вместо того, чтобы код писать.
  • +2
    А мне нравится БЭМ, если его использовать без фанатизма. Вполне себе удобная метода.
  • 0
    Все стили опять в html засунуть.
  • 0
    Однажды, Максим Покровский в своём блоге озвучил потрясающую идею. То, что предлагает Яндекс под названием БЭМ есть развитие этого подхода.
    • +3
      БЭМ в Яндексе развивается с 2005 года. Приведённый вами пост датируется 2009м.
      • 0
        В 2005 об этом точно никто не слышал. Реально тема пошла где-то с 2009.
    • +1
      Статья vitaly.harisov.name/article/independent-blocks.html была написана на год раньше. И комментарии Пепелсбея к этой статье ссылаются на код в Яндексе, который к тому времени уже был в продакшене.
  • +2
    Для БЭМ-а есть BOSS — CSS-препроцессор по типу SASS/LESS, но умеет разворачивать блоки-элементы–модификаторы и позволяет избавиться от ручного написания классов в стилях + добавляет немного плюшек вроде арифметики, миксов и т.д.

    Названия классов в разметке вручную уже давно никто не пишет, все используют bem-tools.

    bem-tools + boss = ♥
  • +2
    Спасибо автору!
    После работы в Яндексе стараюсь применять что-то подобное БЭМ в вёрстке, т.к. это и вправду намного удобнее в разработке, поддержке, рефакторинге, передаче кода и т.д. и т.п.

    Ещё плюс в скорости рендеринга — про это в Яндексе была целая лекция. Основной смысл в том, что css-движки разбирают селектор справа налево.
    Т.е., грубо говоря, для селектора вида ".content a" сначала будут найдены все «a», потом из них выбраны те, у кого есть родитель ".content". Намного быстрее, если будет выбираться сразу ".content__link".

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

    Очень надеюсь, что подобный подход рано или поздно станет стандартом CSS де-факто.
  • 0
    Я пока еще не слишком проникся методикой БЭМ, но за время шапочного знакомства с ним у меня сложилось мнение, что особенно сильно его преимущества видны при применении специального ПО, которое отвечает за генерацию HTML и CSS из шаблона, и за подключение к странице стилей и скриптов блока.

    При этом, если я правильно понимаю, блоки являются строительными блоками, которые подключаются ко многим частям многих страниц, где нужны однотипные элементы. То есть, напоминают виджеты или компоненты, которые применяются в некоторых фреймворках и CMS, только не содержат бизнес-логики. В моем понимании, которое, конечно, не слишком сильно, дело больше не в стиле написания классов, а в методике применения специального ПО.

    Я так понимаю, здесь присутствуют те, кто хорошо разбирается в теме. Хотелось бы узнать, так ли это. И если да, то хотелось бы узнать побольше об этой стороне БЭМ.
    • 0
      Про наш шаблонизатор BEMHTML можно посмотреть видео: clubs.ya.ru/bem/replies.xml?item_no=1153
      • 0
        Спасибо, это интересная информация.
  • +1
    Т.е. нам предлагается выкинуть букву C из CSS? И оставить просто Style Sheets?
    • 0
      Вовсе нет, каскадность ни куда не девается и её нужно учитывать вложенный блок всё равно унаследует стили родителя, просто не нужно описывать стиль вложенного блока используя в селекторе родительский блок — нужно прописать свой класс дочернему блоку и использовать в селекторе только его… А методология помогает создать название класса, чтобы было понятно чтоэ то за блок.
      • 0
        То есть как это? Одна из важных составяющих БЭМ — изолированые блоки. Изолированный именно для того, чтобы стиль не приходил сверху и не уходил дальше, во вложеные блоки. Так что товарищ прав — первую букву в CSS предлагается выкинуть.
        • +1
          Блок должен быть максимально незавим в глобальном контексте страницы, но бороться с элементами внутри этого блока — не разумно. Логично если, скажем, вы создаёте блок со списком и будете использовать во всех элементах чёрный текст — назначить этот стиль на родительский блок и Вы ни куда не денетесь — он пойдёт «вниз» по потомкам. Если же где-то цвет не подойдёт — его можно переопределить в локальном стиле элемента. Т.е. писать абсолютно ВЕСЬ комплект стилей для КАЖДОГО элемента это уже через край. Собственно существование модификаторов подтверждает — иначе предлагалось бы писать новый класс для каждого отличающегося элемента, а так предлагается использовать модификатор, меняющий только нужное свойство.
          • 0
            Я вас не верно понял в первый раз. Конечно каскад никуда не денется. Просто он не войдет во вложенный блок, так как веса не хватит.

            Весь комплект стилей для элементов повторять не нужно, но для блоков при максималистском подходе именно так и нужно делать. Другое дело, что это «полный набор» получается не очень-то и большим — часть засунута в нормалайз/ресет.
        • +1
          От первой буквы — очень хочется избавиться (с ней много проблем). Но в реальном мире — она нужна и ей пользуются.
  • +4
    К стати, касательно скорости набора, и безотносительно холивара БЭМ/неБЭМ — есть такая замечательная штука как Emmet (ранее называлось ZenCoding).
    На Хабре уже неоднократно про нее писали. Но тем не менее, может кто не в курсе.
    Это программа (и одноименные плагины для различных редакторов) для быстрого набора HTML и CSS текстов.
    Повторяться не буду, смотрим здесь:
    в общем о ZenCoding (v0.5)
    о новом в версии 0.6
    о версии 0.7

    А вспомнил я про нее, потому, что в последней версии 0.8 появились т.н. «фильтры», один из которых позволяет быстро верстать в стиле БЭМ: github.com/sergeche/emmet-sublime#yandex-bem-filter

    Примерно так, набираем:
    .b>._m1>._m2|bem
    жмем кнопку, получаем:
    <div class="b">
    	<div class="b b_m1">
    		<div class="b b_m2"></div>
    	</div>
    </div>
    
    • 0
      А вот это уже замечательно. Спасибо за наводку.
    • 0
      Фильтры ещё в 0.7 появились.
      • 0
        А как использовать? У меня на винде .b>._m1>._m2|bem не разворачивается.
        • 0
          У меня разворачивается (Emmet на ST2). Если же вопрос про 0.7, то не уверен, что там был именно фильтр BEM.
          • 0
            Я про седьмой — не обновлял еще. Ок, завтра разберусь, спасибо.
  • 0
    А не подскажете как с помощью БЭМ сделать переключение цветовой схемы не используя вложенность классов?

    Вот такой простой пример: infoexpo.ru/demo/switcher.html

    Я правильно понимаю, что придется при смене схемы кроме добавления одного класса для body еще и переписывать классы у всех элементов?
    • 0
      Если бы там не было JS я бы подумал, что Вам удалось упрекнуть всю концепцию, но там есть JS потому не понятно, что Вас смущает в предложенном Вами варианте? Сменить класс у двух элементов вместо одного как это делается сейчас?
    • 0
      Очень правильный вопрос.
      Мы в своей команде решили, что отказываться от каскада в описанном вами случае — излишний фанатизм.
      • 0
        Дело не в конкретном случае.
        Представьте себе страницу на которой например форма поиска находится и в футере и в шапке страницы. Функционально и структурно они идентичны. Различие лишь в визуальном оформлении. Используя каскад легко перекрасить эту форму не затрагивая html. БЭМ же предлагает навешивать разные классы на семантически идентичные блоки.
        Не кажется ли вам, что тут несколько побоку идет принцип разделения структуры и оформления?
    • 0
      Придется подключить другой css, в котором цвета будут соответствовать новой цветовой схеме.
      Никаких новых классов не требуется.
      • 0
        Запрос на сервер + перерисовка всей страницы?
        Ну чо, продолжайте в том же духе.
        • 0
          когда цветовых схем будет больше чем 2, например 200, и они будут сложнее, чем просто цвет текста в css — приходите, пообщаемся ;)
        • +2
          вы думаете, что поменяв класс для боди — вы не спровоцируете перерисовку страницы? у меня для вас плохие новости :)
          • 0
            Хозяйке на заметку: смена класса — верный способ форсировать перерисовку. Полезно, когда что-то не прорисовывается как надо, например тени.
            • 0
              В IE8− так можно «починить» селекторы с плюсом „+“, например, хватит даже добавления пустой строки:
              el.className += ''
              
            • 0
              Смена класса не выщывает немедленной перерисовки, а ставит её в очередь.

              Чтобы вызвать перерисовку надо заставить браузер пересчитать размеры, например, вызвав offsetHeight
              • 0
                Главное, что она происходит.
    • 0
      Я правильно понимаю, что придется при смене схемы кроме добавления одного класса для body еще и переписывать классы у всех элементов?
      Нет, не правильно. Можно реализовать цветовые схемы через модификатор theme у корневого блока page, задав для body классы page и page_theme_bear и указав изменения внешнего вида вложенных блоков отталкиваясь от этого модификатора.
  • 0
    В этом примере всего два элемента. Немного абстрагируйтесь и представьте себе, что элементов гораздо больше и ведут они себя все по-разному. Ссылки например по тексту меняются с синего на зеленый, иконки меняют картинки. Допустим на странице 50 разных элементов — которые имеют визуальную вариативность одновременно в зависимости и от положения в DOM и от цветовой схемы. В случае с БЭМ мы упремся в бесконечное число классов которые придется навешивать на каждый элемент.
    • +1
      Не знаю чего Вы ожидаете, но я разрешаю Вам не пользоваться БЭМ, так и быть (вычеркнул ankelm из списка пользователей БЭМ)…
      • 0
        Я и так не в этом списке :p
        БЭМ Велосипед на костылях не лучшее средство предвижения. IMHO
    • 0
      В атких случаях, если я ничего не путаю, .scheme .block оправдано. А вот если у вас есть один элемент с разными видами — например, кнопка, то следует создать общий класс .b-button и «цветовые» .b-button_red, .b-button_green и т.п.
      • 0
        В атких случаях, если я ничего не путаю, .scheme .block оправдано.

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

        Разве это нормально когда в простейшем случае нам приходится отказываться от базового принципа?

        В принципе примеров когда семантичнее и проще использовать каскад вместо введения классов можно напридумывать массу.

        • 0
          Смена цветовой схема у множества блоков сразу — это далеко не «простейший случай».
          • 0
            В случае с каскадом в css — это действительно простой случай. .selector-one .selector-two и все в порядке.
            БЭМ же предлагает вынести этот каскад из стилей практически в атрибуты.
            Опять же в этом простом примере можно увидеть, что для реализации смены цветовой схемы через css достаточно верстальщика с минимальным опытом, главное чтобы умел css писать. Для реализации БЭМ придется привлекать уже специалиста с опытом js.
            Конечно, на больших проектах как у Яндекса с его исторически сложившейся архитектурой выгода от подобных методик какая-то есть, но это совсем не означает, что подобный поход стоит популяризировать и преподносить как приближенное к иделу решение.
            • 0
              Не путайте тёплое с мягким. Сложность реализации каскада в обычном CSS-коде такая же, как сложность реализации каскада в CSS, написанном по БЭМ-стайлгайдам.

              p.s. где вы увидели необходимость js в такой схеме — я не очень понял.
              p.p.s. дальше спорить не буду, каждому своё.
              • 0
                где вы увидели необходимость js в такой схеме — я не очень понял

                А как еще классы навесить? Не генерить же новый html на сервере.
    • 0
      Я вам ответил выше, как это решается.
    • 0
      В случае с БЭМ мы упремся в бесконечное число классов которые придется навешивать на каждый элемент.
      Нет, не упрёмся.

      В статье было неверное утверждение ро невозможность использования каскада в БЭМ, от которого пошло непонимание. Я ответил на это тут: habrahabr.ru/post/151931/#comment_5165248
      • 0
        Вот теперь мне БЭМ нравится гораздо больше.
  • 0
    Насчет того, что W3C тупят не соглашусь. Понятно что пока только экспериментально работает в паре браузеров, но продвижение какое-то есть. Это я про стили с ограниченной видимостью(style scoped). Вот эта штука под БЭМ по моему идеологически лучше подходила бы.

    • 0
      Когда будет поддержка со стороны баузеров и с style scoped не будет проблем (например с производительностью) — то, да — это очень хорошо дружит с БЭМ.
      Замечу, даже в W3C продвигаются идеи, похожие на БЭМ и style scoped тому пример :)
  • +1
    Как такое реализовать в концепции БЭМ?

    .some-block .extra-content {
    display: none;
    }

    .some-block:hover .extra-content {
    display: block;
    }

    С приходом CSS3 и HTML5 надо стараться перестать думать о вёрстке, как о чём-то чисто статическом.

    Плюс, не всегда удобно сказать — «надень чёрные перчатки, надень чёрные носки, надень чёрный костюм, надень чёрную шляпу», бывает проще сказать — «надень чёрный костюм» и описать, что именно входит в это описание костюм. И это относится к использованию CSS-классов в JavaScript-коде, где цеплять скин по частям к каждому дочернему компоненту может превратить в код на сотню строк.
    • 0
      так и реализовать, используя наследование
      • 0
        Вкратце вся система БЭМ укладывается в 2 тезиса (принципа/правила):

        Нет селектора кроме класса — т.е. никаких стилей повешанных на теги, ID и прочее, только классы.
        Нет вложенных селекторов — т.е. никаких .class1 .class2{ display: none; }, всё определяется 1 (одним) селектором класса (плоская/одноуровневая структура стилей/селекторов).
        • 0
          Реальный мир более жесток. Концепция БЭМ предлагает отказаться от каскадов там, где от них можно отказаться, но есть случаи когда каскад оправдан.
  • +3
    Спасибо за статью!

    В ней есть некоторые неточности, хочу на них ответить как один из создателей БЭМ и текущий Team Lead команды разработки БЭМ в Яндексе.
    • 0
      Яндекс даже полез в W3C (связано это или нет — не знаю, но надеюсь, что да).
      Нет, это никак с БЭМ не связано.
      • 0
        Про вступление в W3C будет доклад на YaC от Charles McCathie Nevile.
    • +1
      На самом деле это просто мой взгляд на БЭМ и почему я его стал использовать. Как раз та самая точка зрения человека верстающего и вносящего правки в вёрстку к небольшим штучным проектам. Буду рад внести правки и уточнения.
    • 0
      Вот у меня сайт, вот вёрстка не по БЭМ, почему я должен всё менять?
      Про это был подробный рассказ на Я.Субботнике в Ебурге в прошлом году: clubs.ya.ru/bem/replies.xml?item_no=864
    • 0
      Нет вложенных селекторов — т.е. никаких .class1 .class2{ display: none; }, всё определяется 1 (одним) селектором класса (плоская/одноуровневая структура стилей/селекторов).
      Это утверждение неверно.

      Вложенные селекторы могут быть при

      1) определении стилей одних блоков/элементов внутри других для изменения их вида. Например, если надо изменить блок link при вхождении его в элемент tab блока head: .head__tab .link { color: blue }

      2) изменении вида элементов блока в зависимости от его модификатора: .head_size_big .head__tab { font-size: 150%; }

      Ну и любые другие варианты, когда надо изменить один блок/элемент в контексте другого блока/элемента/модификатора.
    • 0
      Примечание: согласно нотации БЭМ Модификатор отделяется от Элемента одиночным подчёркиванием.
      Модификатор состоит из пары ключ-значение.

      Одному ключу может соответствовать несколько значений.

      В примере с .content__link_ajax надо писать .content__link_type_ajax или .content__link_ajax_yes в зависимости от наличия других значений для модификатора и ваших предпочтений.
    • +1
      Спасибо! Обновил текст статьи.
  • 0
    Сейчас на западе популярен альтернативный, но похожий на БЭМ подход – SMACSS.
  • 0
    Напрашиваются паттерны программирования: наследование и типизация. Добавляем немного хорошего тона: «никаких стилей повешанных на теги» и получаем то что яндекс назвал БЭМ.
    Вспомните как пишутся плагины\виджеты для того же jquery, максимально абстрагировано от внешнего мира.
    Ещё по-моему сюда стоит внести запрет на использование "!important" и вот уже готов первый набор инструкция для CSSLint.
    • 0
      С наукой всегда так — когда её соберут и систематизируют — начинает казаться, что это и так было очевидно…
  • 0
    подозреваю что пресловутый БЭМ будет хотя бы не вреден только на большом проекте с однотипными блоками которые подключаются куда попало и поддерживаются независимо.

    Вопрос на засыпку
    — насколько увеличивается параметры страницы — размер, размер css, количество правил в css
    — насколько меняется время onload?

    Очевидно что less и прочие семантические препроцессоры более человекопонятны.
    Может ли Я предложить свой препроцессор из less, sass и прочего в БЭМ?
    • 0
      БЭМ одна из тех вещей которую подозревать не надо — надо проверять. Потому, что из всех вышевысказанных комментариев большая часть отрицательных — умозрительная, а большая часть положительных — практическая.

      И в 500й раз — less, sass не мешают БЭМ, как и он им, просто less в терминах БЭМ не будет использовать вложенные селекторы, там где можно обойтись без них и селекторы не классы. Всё остальное — функции, переменные, рассчёты — только плюс…
      • 0
        ага, кэп, это очень познавательно, но хотелось бы слышать ответы на вопросы.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.