Масштабирование наоборот: БЭМ-методология Яндекса на небольших проектах

В разработке интерфейсов отдельные фреймворки уже не так важны: когда инструменты доступны, наша задача сводится к выбору нужных. Чтобы сделать правильный выбор, нужно начать с общего подхода, с методологии. Большинство методологий, однако, разработаны крупными компаниями. Применимы ли они в маленьких проектах или их нужно «переизобретать» заново для успешного использования? Скорее всего, вы уже знаете об одной из таких методологий, разработанной Яндексом — БЭМ. БЭМ утверждает, что трёх сущностей (блоков, элементов и модификаторов) достаточно для написания HTML и CSS, задания структуры кода и компонентной структуры с последуюшим масштабированием проекта до самого высокого уровня.

bcba281ac5b244a69aca746b27714d15.jpgЯ проработал в Яндексе достаточно долго и видел, как эта методология работает на больших проектах. В Яндексе БЭМ используют для разработки CSS- и JavaScript-компонент, с помощью этой методологии также пишут шаблоны и задают зависимости между компонентами. Есть БЭМ-инструменты, поощряются различные эксперименты с кодом, исследования. В масштабах большой компании эти трудозатраты окупаются и дают Яндексу возможность разрабатывать сотни сервисов одновременно — быстро и качественно.Могут ли маленькие команды получить от БЭМ то же самое? В этом я совершенно не был уверен. Всё же БЭМ — абстракция, которая поставляется вместе с инструментами и технологиями. Для маленькой компании польза от переключения на «полный стек» этих технологий — сомнительна, многие из инструментов изначально приспособлены под крупные и сложные задачи. Быть может тогда сама идея, сама методология окажется полезной?

Изначально эта моя статья была опубликована в известном многим журнале Smashing Magazine. Но я решил, что и на Хабре она может быть интересна, ведь многие здесь занимаются собственными небольшими проектами.

К вопросу о том, может ли BEM применяться в таковых, я вернулся чуть более года назад, когда переехал в Берлин для работы в небольшой стартап-компании Deltamethod. Планы на разработку у компании были смелые, и мы с командой решили попробовать БЭМ-подход. Хотелось получить те же бонусы, что были у Яндекса: переиспользование кода, «живой» Style Guide, масштабируемость и быструю разработку. В дополнение к этому, мы хотели в целом сохранить используемый стек технологий и улучшать код постепенно, а не переписывать весь сервис с нуля.

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

Основы БЭМ Давайте вспомним основы.Утверждается, что семантика — это фундамент веб разработки, но различные frontend-технологии используют разные семантические модели. Современное веб-приложение на уровне HTML чаще всего — просто нагромождение тегов div и span. CSS как технология вообще не предлагает какой-либо структуры. Высокоуровневые JavaScript-компоненты используют те или иные абстракции, но они слабо связаны с CSS или HTML-разметкой. С точки зрения дизайнеров и UX-специалистов, интерфейсы вообще описываются терминами, далекими от технической реализации. Тем не менее, все эти предметные области мы используем вместе. Самое время вспомнить про БЭМ: ведь это общая семантическая модель для разметки, стилей, кода и UX. Посмотрим поближе.

Блоки Блок — это независимая сущность со своим собственным смыслом, он представляет на странице отдельный «кирпичик» интерфейса.Например, блоками могут быть:

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

Элементы Элемент — это часть блока, связанная с ним и по смыслу, и функционально. Без блока, к которому он относится, элемент не существует и не используется. Но не у всех блоков должны быть элементы.Примеры элементов:

навигационное меню (блок), содержащее пункты меню (элементы), таблица (блок), внутри которой строки, ячейки и заголовки (элементы). У элементов тоже есть названия. Если внутри блока несколько одинаковых элементов, то они идут под одним именем (например, ячейки таблицы или пункты списка). Элементы определяются по смыслу, а не исходя из HTML-вёрстки блока; так, отдельный элемент может быть представлен сложной HTML-структурой.Модификаторы Модификаторы — флаги у блоков или элементов, они определяют свойства или состояния. Модификаторы могут быть булевыми (например, visible: true или false) или представлять из себя пару ключ-значение (code>size: large, medium, small). Это чем-то похоже на атрибуты в HTML, но всё-таки не то же самое. У сущности может быть несколько модификаторов, если эти модификаторы описывают разные вещи.Блоки в DOM Как использовать БЭМ, если мы всё ещё вынуждены писать HTML? Нужно соглашение об именовании, которое свяжет DOM-узлы с БЭМ-сущностями.Для задания этой связи БЭМ использует CSS-классы. При этом блоки, элементы и модификаторы не размещаются на DOM-узлах «эксклюзивно»; на одном теге может быть определено сразу несколько блоков либо же элемент блока может быть объединен с контейнером другого блока. Использование одного и того же DOM-узла для размещения нескольких сущностей называется «микс». Помните, что «миксы» сделаны для удобства, совмещать можно только совместимое: смешивая блоки и элементы, не преврашайте всё в кашу.

Дерево БЭМ (BEM tree) Формируя документ из БЭМ-сущностей, начиная с корневого блока ( или даже ) и заканчиая самыми глубоко вложенными блоками, вы создаёте семантический слой поверх существующей DOM структуры.Этот слой называется БЭМ-деревом (или BEM tree по-английски).

БЭМ-дерево даёт возможность взаимодействовать с целым документом в терминах БЭМ с точки зрения семантики, сильно абстрагируясь от особенностей DOM-реализации.

Первые шаги Если вы уже задумываетесь, не попробовать ли БЭМ на проекте, возникает закономерный вопрос: «Как перевести на БЭМ существующий проект, можно ли это сделать постепенно? «Конечно, можно. Давайте начнем с того, чтобы выделить несколько блоков. Мы начнём только с семантики, а конкретные технологии (такие как CSS и JavaScript) обсудим позже.

Как вы помните, только самостоятельная сущность может быть блоком.

Например, заголовки — это блоки. У них нет внутренних элементов, но уровни заголовков (от самого большого до самого маленького) могут быть определены как модификаторы вида ключ-значение.

Если позже понадобятся ещё уровни, мы определим дополнительные модификаторы. Тут я скажу, что разработчики HTML4 были скорее всего неправы, изобретая

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

Скажем, мы получили такое:

BLOCK heading MOD level: alpha, beta, gamma В качестве второго примера можно взять форму. Её элементы управления (или, как их называют, контролы: поля ввода, кнопки, чекбоксы и пр.) тоже являются блоками. В HTML это всё реализовано довольно беспорядочно. Разные по сымслу вещи (поля ввода, радио-кнопки и флажки-checkbox’ы) объединены в один тег , a другие (сильно похожие на них) определены отдельными тегами