Хабрахабр

Удобный БЭМ

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

Она вводит понятия блока, элемента, модификатора и микса. БЭМ — это методология, позволяющая использовать CSS/HTML/JS много раз. Но спустя некоторое время начинают встречаться такие моменты в разработке, которые решить с помощью БЭМ можно, но это не приносит ни удовольствия, ни, главное, пользы. Начав ее использовать, ты понимаешь, что это именно то, чего ты ждал много лет, это так удобно, понятно и красиво! Пройдемся по таким моментам: О чем я говорю?

1. Одноразовые блоки и элементы

Данная проблема так сильно мне надоела, что заставила написать эту статью.

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

Например, нам нужно сделать следующее: расположить на странице заголовок, за ним — текстовое поле и кнопку отправления ввода, так, как показано на картинке:

Есть несколько вариантов: Что мы сделаем в соответствии с БЭМ?

  1. Создать блок формы и его элементы: заголовок, кнопку, текстовое поле
  2. Создать отдельно блоки для каждого из компонентов (кнопка, текстовое поле, заголовок), а также для формы
  3. ...

Какой бы мы ни выбрали, у нас возникнет проблема: как задать отступы между всеми этими блоками?

Однако в этом случае мы уничтожаем суть блока: он не может быть переиспользован, так как его внутренняя разметка подойдет только к текущей ситуации. Если мы выбрали первый вариант, то можно решить задать отступы для элементов формы, ведь это не противоречит методологии.

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

Данная проблема порождает одноразовые блоки/элементы, а также модификаторы типа блок__элемент_size_размер или блок__элемент_place_место-где-будет-расположен-блок (для задания отступов), которые, как уже было сказано, используются один раз и загромождают как файлы разметки, так и проект собственными директориями и файлами.

То же самое касается не только отступов, но и размеров блоков (для кнопок, например, это часто тянет за собой изменение еще и line-height'ов), размеров шрифтов, внутренних отступов и т.д.

2. Длинные имена классов

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

<header class="section-header section-header_margin_select-sector"> <h2 class="section-header__title font font_face_calibri-bold section-header__title_size_select-sectors"> Select a sector, please: </h2>
</header>

3. Значения по-умолчанию или темы блоков

Предположим, у нас есть блок кнопки. Нужно её стилизовать в соответствии с требованиями дизайна. Но в другом проекте тоже будет класс кнопки. Она будет выглядеть по-другому, однако некоторая часть стилей будет одинакова. Что советует делать БЭМ? Он говорит создать модификатор темы и задавать его всем требуемым элементам.

Но при таком подходе получится следующее:

<input type="text" class="textbox textbox_theme_P2">
<button class="button button_theme_P2">Reset</button>
<button class="button button_theme_P2">Submit</button>
<button class="button button_theme_P2">Save as draft</button>

Это загромождение кода, и это плохо.

Критикуешь — предлагай

Что я предлагаю, чтобы исправить это безобразие? Я предлагаю следующий манифест, который, по сути, является надстройкой над стандартным БЭМ.

Манифест — Improved BEM

П.1 Слой модулей и слой страницы

Я предлагаю разбить стилевое оформление на две части:

Эта часть пишется в соответствии со всеми (почти*) правилами БЭМ. Первая часть — слой модулей (components layout). Она задает стили для переиспользуемых блоков, или, лучше сказать, компонентов, например, для кнопки, текстового поля, заголовка и т.д.

Он требуется для задания стилей блоков и элементов конкретной страницы. Другая часть — слой страницы (page layout). Здесь правила БЭМ не действуют. Соответственно, эти блоки/элементы будут использованы один раз (во всяком случае, на одной странице). Выглядит это так:

Файл: index.css

.___send-button { margin-bottom: 2px; font-size: 13px;
} .___message-textarea { width: 240px; height: 300px; font-size: 14px;
}

Имя файла page layout'а выбирается произвольно. Главное, чтобы оно соответствовало сути страницы. Все стили начинаются с '___', чтобы их нельзя было спутать с классами стандартных сущностей БЭМ. Также классы не привязаны к БЭМ-сущностям — их имена лишь отражают то, к чему они должны применяться. Ещё стоит заметить, что все стили page layout'а располагаются в одном файле, так как относятся к одной странице.

Данные стили будут применяться только на одной странице и никоим образом не будут мешать стилям компонентов из components layout. Данное разделение позволяет решить первую проблему, при этом не нанеся ущерба главной цели БЭМ — создания стилей/разметки так, чтобы их можно было переиспользовать. Таким образом, мы избавляемся от одноразовых классов, сохраняя возможность переиспользовать блоки и не нарушая областей видимости.

Также имеет смысл разделить components и page layout'ы и на уровне директорий.

*кроме правил, которые отменяются следующими пунктами манифеста.

П.2 Длинные имена классов

(Экспериментальный, поэтому опциональный пункт*)

Предлагается заменить часть стандартной системы именования на следующую:

Для блока: class="блок" (без изменений)
Для блока с модификатором: class="блок _модификатор" (обращение через комбинированный селектор .блок._модификатор)
Для элемента: class="блок__элемент" (без изменений)
Для элемента с модификатором: class="блок__элемент _модификатор" (обращение через .блок__элемент._модификатор)

Очевидно, почему нельзя сделать то же самое с элементами. Данный пункт позволяет получать краткий код в отношении модификаторов.

Важно, чтобы в файлах со стилями не было правил, заданных для селекторов, которые состоят только из модификаторов:

/*Неправильно!!!*/
._active { background-color: #abcdef;
}

*подобное именование модификаторов может привести к проблемам на блоках/элементах, смиксованных с другими блоками/элементами, при условии, что обе сущности могут иметь одинаковый модификатор. То есть, задавая модификатор для одной сущности, мы задаем его для всех примиксованных к этому узлу.

П.3 Значения по умолчанию и темы

Тут все просто. Предлагается выбрать тему по умолчанию, но прописывать стили для нее не в классе блока, который находится в файле блока, а в классе блока, который следует разместить в файле с темой. Например:

Файл — button/button.css

.button { cursor: pointer; display: inline-block;
}

Файл — button/_theme/button_theme_P2.css

.button_theme_P2,
.button { border-radius: 3px; border: 1px solid #f00;
}

Или в соответствии с п.2

.button._theme_P2,
.button { border-radius: 3px; border: 1px solid #f00;
}

Таким образом, данная тема становится стандартной, но при желании можно использовать её непосредственно.

Итог

Данный манифест призван решить некоторые проблемы, возникающие при верстке в соответствии с БЭМ. Основной его составляющей было разбиение на components layout и page layout. Хотя выглядит манифест достаточно революционно, неканонично и смело, заявленные проблемы он решает. Использовать его весь, частично или не использовать вообще — решать, конечно, вам.

S. P. Если вы сейчас гневно проскроллили всю страницу чтобы поставить минус, не забудьте написать комментарий, иначе пользы ваш минус не принесет (как и манифест).

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

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

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

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

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