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

Аббревиатура BEM — блок/элемент/модификатор. Любой макет или дизайн можно визуально разбить на блоки, к примеру — sidebar сайта. В каждом блоке могут содержаться один или несколько элементов. У элементов могут быть модификаторы состояния (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 { 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 как вложенность элементов в класс и удлинение имён на ровном месте:
<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, подталкивает разработчика к хардкоду. Буду рад похвале методологии в комментариях, будет пища для размышлений.
ссылка на оригинал статьи https://habr.com/post/422537/
Добавить комментарий