Хабрахабр

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

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

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

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

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

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

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

<ul class="article-rewind article-rewind_type_static article-rewind_lang_ru"> <li class="article-rewind__next"> <div class="article-rewind__next-text">Читать далее</div> <a class="article-rewind__next-link" href="">Основные понятия</a> </li>
</ul>

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

<ul class="article-rewind type-static lang-ru"> <li class="next"> <div class="text">Читать далее</div> <a class="link" href="">Основные понятия</a> </li>
</ul>

.article-rewind &.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 как вложенность элементов в класс и удлинение имён на ровном месте:

<h1 class="article__heading_level_1 article__heading_level_1_active"></h1>

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

<h1 class="heading active"></h1>

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

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

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

<div class="promo-section promo-section_color_white"></div>

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

<div class="promo-section background-white"></div>

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

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

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

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

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

<h1 class="article__heading article__heading_level_1"></h1> <h2 class="article__heading article__heading_level_2"></h2> <h3 class="article__heading article__heading_level_2"></h3>

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

<h1 class="heading"></h1> <h2 class="heading"></h2> <h3 class="heading"></h3>

@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, подталкивает разработчика к хардкоду. Буду рад похвале методологии в комментариях, будет пища для размышлений.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть