[Из песочницы] BEM'a не должно существовать

mo8bkqqcnrfp9bokusxs3w6umdq.gif


Здравствуйте.

BEM’а не должно существовать. Есть огромное количество причин не использовать эту методологию, но из-за её простоты использования и непонимания работы CSS и HTML, методология широко распространилась среди фронтендеров всего мира, в большинстве случаев среди разработчиков СНГ. Используется BEM сейчас как на больших русскоязычных проектах (Yandex, Habr), так и в некоторых фреймворках (react-md). В этой статье пойдёт подробный разбор плюсов и минусов этого подхода к разработке. Все примеры вёрстки будут взяты с официального сайта BEM.
kjwnauugv8k8megcfjufizujk8c.jpeg

Аббревиатура BEM — блок/элемент/модификатор. Любой макет или дизайн можно визуально разбить на блоки, к примеру — sidebar сайта. В каждом блоке могут содержаться один или несколько элементов. У элементов могут быть модификаторы состояния (active, disabled), дополнительные классы для изменения границ, ширины, цвета фона и т.д.

Идея разбития макета на блоки не новая, что нам предлагает BEM — удлинять имена классов, всегда делать элементы зависимыми от названия блока и задавать любой класс глобально. Помогает это буквально нигде и приводит к печальным последствиями в вёрстке проектов. Ниже описаны по пунктам проблемы в использовании BEM’a:

Нечитабельный html


Это вёрстка с официального сайта BEM. Удлинённые и php-подобные названия CSS классов делает любую вёрстку абсолютно нечитабельной вперемежку с атрибутами:




Ниже предоставлен образец вёрстки без наследования в имени класса названия блока, модификаторы привязываются к главному классу через наследование в SCSS, а не текстовое название класса:



.article-rewind {
  margin:      0;
  padding:     0;
  list-style:  none;
  &.type-static {
    position:  relative;
    display:   flex;
  }
  &.lang-en {}
  &.lang-ru {}
  &.lang-uk {}
  & > .next {
    position:      relative;
    flex-grow:     1;
    align-self:    center;
    margin-right:  88px;
    text-align:    right;
    .text {
      font-size:   16px;
      position:    absolute;
      right:       0;
      margin-top: -32px;
    }
    .link {
      font-size:   40px;
      line-height: 46px;
    }
  }
}

Сложности с наследованиями модификаторов


Любой класс в BEM — глобальный, и модификаторы — не исключение. Там, где CSS позволяет основному классу, например, button наследовать несколько классов active, disabled, error, вы будете задавать всё это глобально, наследуя в имени родительские имена блоков и элементов. Такой подход — игнорирование возможностей CSS как вложенность элементов в класс и удлинение имён на ровном месте:

    


Пример наследования модификаторов через SCSS, а не через слова в имени класса:

    

.article {
  h1.heading {
    font-size:   50px;
    line-height: 64px;
    float:       left;
    &.active {
      color:     #ccc;
    }
  }
}


Все классы — псевдо-глобальные


По сути, в глобальных классах нет ничего плохого. Проблема в том, что в названии класса сохраняется имя блока или элемента и использовать его вне блока уже нельзя и глобальность становится бесполезной. Плюс ко всему в браузере висят глобальные классы, к примеру promo-section_color_white который всё что делает — меняет цвет фона на белый, причём применить это можно только к блоку .promo-section. Для других блоков с белым фоном делайте новый класс с хардкодом в названии. Элементы не могут быть использованы везде в проекте, хотя и применять классы технически возможно везде:

  


Вместо привязки к блоку через текст в html, можно сделать классы по-настоящему глобальным, переиспользовать на других секциях и абсолютно ничего не потерять:

  
.promo-section {
  position: relative;
  padding:  0 0 70px;
}
.background-white {
  background-color: white;
}


Запрещение использования семантики


Дословная цитата из документации:

В CSS по БЭМ также не рекомендуется использовать селекторы по тегам или id

В местах, где можно с помощью mixin’a или цикла в препроцессоре воспользоваться наследованием через html-тег вы не можете этого делать:

  


Здесь стили можно было задать через h1, h2 и так далее, но теперь вместо ссылки на тэги мы глобально имеем заданный класс «article__heading_level_1».

  

@for $index from 1 through 6 {
  h#{$index}.heading {
    font-size: (42px / $index);
  }
}

/* mixin output */
h1.heading {font-size: 42px;}
h2.heading {font-size: 21px;}
h3.heading {font-size: 14px;}
h4.heading {font-size: 10.5px;}
h5.heading {font-size: 8.4px;}
h6.heading {font-size: 7px;}


Подразумевает вёрстку только блоками


В каждом большом темплейте есть мелкие элементы, как кнопки, дропдауны, тайтлы, субтайтлы, секции и т.д. Но в БЭМе у вас их нету, так как любой элемент без блока использовать тоже запрещено.

Элемент — всегда часть блока и не должен использоваться отдельно от него.

Хотите дропдаун не только в хэдере? На сайте BEM’a дропдаун в header’e свёрстан как попап, лежащим в корне body. По сути, этот пункт является запрещением создания полноценного темплейта, а не чего-нибудь сложнее лэндинга.

Плюсы


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

© Habrahabr.ru