для чего нужен бэм
Почему лучше верстать в соответствии с БЭМ — практические примеры
Про БЭМ (методология написания CSS от Яндекс — Блок__Элемент_Модификатор ← наиболее правильная запись расшифровки) нынче можно услышать на каждом шагу. Дело оказалось благим и покатилось по миру. Яндекс даже полез в W3C (связано это или нет — не знаю, но надеюсь, что да — [на самом деле нет]).
Думаю многие, кто ещё не пробовал, но прочитал описание БЭМ, задаются справедливым вопросом: «какая практическая польза от всего этого действа?» На самом деле, не смотря на то самое развёрнутое описание, конкретно уловить основную «фишку» довольно сложно. Описано конечно много плюсов и общее ощущение от методологии положительное, и кажется, что вроде как и не плохо бы попробовать, но нехватает чего-то конкретного. Прямо вот примера на живом что ли. Вот у меня сайт, вот вёрстка не по БЭМ, почему я должен всё менять? Особенно, если учесть тот факт, что БЭМ в принципе отметает все селекторы кроме классов, неужто за это время столько умных мужей в W3C не осознали, что всё настолько неправильно?
За сим возьму на себя смелость привести несколько примеров с которыми вы (конечно если вы каким-то образом связаны с вёрсткой) сталкиваетесь, не побоюсь этого слова, ежедневно. И что изменится в таких ситуациях если бы вёрстка была изначально выполнена в БЭМ.
Немного о БЭМ
Вкратце вся система БЭМ укладывается в 2 тезиса (принципа/правила):
Естественно такая компания как Яндекс не могла просто так придумать себе геморрой чтобы с ним мучиться до конца дней — для этой системы были причины и именно о них (некоторых из них, с точки зрения простого смертного) я попробую рассказать.
Реюзабельность (повторное использование)
Собственно всё именно из-за этого. Особенно первое правило. Но дальше на обещанных примерах.
Пример 1
Допустим вы заказали вёрстку на аутсорсе. Или вы вошли в проект, который существует давно и всё уже свёрстано до вас. В общем на руках типичные стили вроде:
и всё работает, но — добавили аяксов и решили AJAX линки в контенте делать без подчёркивания и другим цветом. Мы не можем решить эту проблему добавив класс ajax-link к аякс ссылкам — CSS так не работает. Стиль ссылки в контенте описан селектором из 2х элементов, а это больше чем наш один стиль. Поможет a.ajax-link, если будет стоять в css файле после предыдущего определения.
Теперь предположим, что content это не класс а ID — думаю с таким тоже сталкивались не раз.
Пример 1pro
Т.е. чтобы перебить такое:
Пример 2
Допустим у нас есть стили вроде таких:
Работа БЭМ
Тут на передовую выходят все прелести БЭМ позволяющие использовать как природную каскадность (наследование вложенными элементами стилей родительских элементов) CSS так и возможность изменить/использовать повторно в другом окружении элементы.
Во-первых, в БЭМ нельзя писать вложенные селекторы, т.е. изменить любой элемент можно просто добавив к нему новый класс и расположив описание его уникального стиля ниже основного описания.
Во-вторых, в БЭМ нельзя использовать в качестве селекторов ничего кроме классов.
Думаю вы уже начинаете догатываться, что сейчас получится.
Пример 1 и 1pro
Согласно первому принципу имя тега не может быть селектором (для 1) также как и id (для 1pro) добавляем сюда второе правило и стиль ссылки в контенте вырождается до:
Примечание: согласно нотации БЭМ Блок content содержит Элемент ссылки link их разделяют двойным подчёркиванием [и состоит из пары ключ_значение ].
Примечание: согласно нотации БЭМ Модификатор отделяется от Элемента одиночным подчёркиванием.
Т.е. тег будет выглядеть примерно так:
Пример 1pro выглядел бы где-то так:
Минусы
Естественно ни что не идеально и концепция БЭМ тоже. В первом случае нам придётся писать класс у каждой ссылки, что не пришлось бы делать при классическом подходе, но опыт показывает (кстати на это часто ссылаются в самом руководстве), что лучше всё же их прописать. Тем более, что сейчас HTML страницы редко когда целиком пишутся руками, так что придётся просто добавить несколько стилей в ваш движок. Ну и, конечно, всегда же есть стили по-умолчанию. Ни что не мешает прописать их в начале CSS файла (тот же сброс стилей). Главное чтоб никакой теговый селектор не был вложенным, только первый уровень и только плоская структура.
Пример 2
Тут уже всё очевидно, но для полноты картины — стили в БЭМ выглядели бы примерно так:
По задачам второго примера у нас выходит, что чтобы выполнить задачу нам вообще стили трогать не надо — достаточно изменить 1 тег HTML вёрстки. Собственно в этом месте лишнее прописывание стилей становится оправданным…
Выводы
Немного личного опыта. Первая попытка разобраться была… первой попыткой. Я пытался понять что, зачем и куда + работа с Twitter Bootstrap и я верстал сам. Потом пошёл на другой проект где вёрстку стали давать готовую, но надо рихтовать при введении новых фишек. Вот тут я отчётливо ощутил все проблемы классических стилей. В итоге я просто стал заменять их на БЭМ по мере необходимости. Одно совершенно очевидно — кастомизировать и повторно использовать БЭМ несомненно легче. А отрыв стилей от семантики (те же теги заголовков, выделения и т.п.) позволяет менять теги не беспокоясь о внешнем виде — в большинстве случаев он не разрушится (если версталось по БЭМ полностью без учёта стилей тегов) или будет легко поправим, а значимость элементов для поисковой индексации можно будет изменять.
Как перейти, если конечно если вы решили принять БЭМ в своё сердце.
PS: Примечания в квадратных скобках добавлены на основании комментариев vithar.
Верстка для самых маленьких. Верстаем страницу по БЭМу
Недавно хабраюзер Mirantus написал статью «Как сверстать веб-страницу», в которой рассказывал о том, как же сверстать веб-страничку. В его статье было подробно рассмотрено, как выделить отдельные элементы из заданного шаблона, подобрать шрифты и т.п. Однако его подход к написанию, собственно, веб-страницы мне показался не очень хорошим, о чем я написал в комментариях.
В данной статье я хочу рассказать, о том, как можно сверстать «хорошо» (по крайней мере структурировано ;), а заодно рассказать и о методологии, которая может «упростить жизнь» при верстке. Структура поста будет следующей:
БЭМ (Блок, Элемент, Модификатор) — методология разработанная внутри Яндекса предлагает следующую концепцию (если описать 1-2 предложениями):
Любая веб-страница — набор блоков, которые состоят из элементов, причем элементом может быть другой блок (таким образом мы получаем вложенность). При необходимости мы можем модифицировать «стандартное» отображение блока\элемента, путем добавления к нему модификатора.
Очень хорошее «руководство к действию» можно найти здесь: ru.bem.info/method/definitions
Предлагаю дать определения основным элементам:
Блок — часть страницы, являющаяся логически независимой от остального наполнения. Представляет собой «строительную единицу» для сайта (на примере конструктора лего — это отдельный «кирпичек»)
Блок не отвечает за свое расположение. Он задает внутренние свойства (размеры, шрифты и т.д.)
Внутри Блок содержит Элементы. Элемент — часть блока, которая отвечает за отдельную задачу (например, это расположение внутри блока). Элемент должен входить в состав блока и не должен иметь какого-либо смысла отдельно от блока.
Пример выделения блоков\элементов
Для примера возьмем блок «прямой эфир» на сайте Хабра:
Вот так он выглядит:
Если «организовать» его по методологии БЭМ, то данная часть будет являть собой блок, состоящий из элементов:
Соответственно, данный блок состоит из 3 разных типов элементов. (Здесь стоит сделать оговорку, что возможно сверстать с использованием только 1 типа элемента (который будет описывать только маргины)).
Элементы выделенные розовым цветом внутри себя содержат другой блок, назовем его «пост».
Соответственно, рассмотрим из чего состоит блок пост:
Таким образом, блок «пост» состоит из 5 элементов.
На данном примере мы рассмотрели каким образом могут строиться блоки с применением методологии БЭМ (стоит сказать, что таким же образом может строиться любой уровень вложенности).
Теперь рассмотрим третью составляющую БЭМ — модификатор.
Модификатор может задавать как дополнительное поведение для блока\элемента, так и переопределять стандартное.
Самым ярким примером для понимания «модификатора» служит пример с кнопками.
Предположим, что в проекте используются кнопки типа:
Готово! В проекте появились красные кнопки с другим внешним видом. Причем нам не понадобилось создавать новые сущности.
Стиль описания БЭМ
БЭМ не декларирует «особого» стиля описания классов. Однако, де-факто используется следующий стиль:
1) Несколько слов в одном названии разделяются дефисом (например, блок main-page или my-super-main-list)
2) Элементы отделяются от блоков с использованием двух символов подчеркивания «__» (например, main-page__header или my-super-main-list__item)
3) Модификаторы отделяются одним символом подчеркивания «_» (например, main-page__header_strong или my-super-main-list_blue)
Префиксы
Иногда в проекте присутствуют префиксы. Они позволяют разработчиком точно определять какую логическую нагрузку несет тот или иной класс.
Например:
g- (global) префикс для глобальных классов. (Например, для задания невидимых элементов g-hidden.)
b- (block) префикс для выделения элементов, относящихся к структуре документа.
js- (JavaScript) префикс для выделения элементов для селекторов js.
Разметка страницы
Разметкой страницы занимается блок, который, к примеру, можно установить для body.
Соответственно элементы данного блока и описывают расположение остальных блоков на веб-странице.
Почему использование каскада — плохо?
Данный способ проще записывается, но, к сожалению, может нарушить независимость блоков.
Пример:
имеем следующую стуктуру:
Именно поэтому, корректной структурой для БЭМ будет:
Какие плюсы дает БЭМ?
0) Независимость блоков — за счет ухода от каскадности и отказа от описания в блоке «своего позиционирования»;
1) Повторяемость блоков — любой независимый блок можно повторять на любых страницах проекта. Возможно создать базу блоков, вследствие чего новые страницы будут создаваться подобно конструктору Лего;
2) Простота поддержки;
3) Структурированность кода.
Страница, сверстанная с использованием БЭМ может выглядеть больше, чем страницы, сверстанные без использования данной методологии, однако, представьте, если вы работаете с сайтом, где >20-30 уникальных страниц? В таком случае возможность повторного использования блоков и единая концепция позволяет:
1) намного быстрее принимать решения о модернизации страниц\блоков сайта;
2) уменьшает порог вступления в проект новых разработчиков.
Верстаем страницу
В качестве шаблона воспользуемся Corporate Blue.
Верстать будем главную страницу:
Изначально определим разметку страницы:
Здесь блок имеет 6 элементов.
По порядку:
1) Верхняя линия
2) Header
3) Меню
4) Слайдер
5) Main
6) Footer
Запишем эту структуру:
Зададим стили для блока и элементов:
Разберем header страницы
Он состоит из двух элементов:
Выделим картинку и зададим HTML-структуру:
В данном блоке мы расположили элементы блока b-head слева и справа, а для input поиска задали стиль отображения inline-block.
Реакцию на работу кнопок\ссылок создавать не будем, так как цель статьи — показать на примере как можно верстать, используя БЭМ.
Переходим к меню
Заметим, что каждый элемент можно представить как самостоятельный блок (состоящий только из себя) и являющийся ссылкой. Заведем сущность ссылка (b-link) и определим для нее обычный стиль и шрифт для ссылки:
Остается только добавить стили и меню готово:
HINT: Если стоит задача сверстать набор элементов на полную ширину родителя, причем все элементы должны занимать одинаковое место, то решением можно считать:
1) Родителю задаем display: table; table-layout:fixed;
2) Дочерним элементам задаем display: table-cell;
Такое моделирование таблицы позволяет успешно решить поставленную задачу.
Переходим к слайдеру:
Здесь текст на слайдере необходимо вывести на картинке. Соответственно, для этого можно использовать картинку (на которой написать вручную текст), а можно воспользоваться особенностью position, либо z-index.
Второй способ гласит, что элементы с position: relative\ absolute отрисовываются отдельно от «остальных» элементов. Соответственно, эти элементы будут отображены «выше» остальных.
Третий способ: z-index задается для сестринских элементов. Представляет собой отображение по оси 0Z. Соответственно, тот элемент, у которого z-index выше, будет перекрывать собой те, у которого z-index ниже.
Зададим HTML структуру:
Меню слайдера не использует так как предполагается, что при нажатии меняется текущее содержимое слайдера.
Main-блок
Основной блок состоит из 6 элементов, каждый из которых содержит блок, наполненый:
а) картинками
б) текстом
в) ссылками
Блоки различаются между собой по ширине и высоте. Если высота будет вычислена при отрисовке страницы, то ширину мы можем задать разную с помощью модификаторов к элементам, в котором содержатся блоки. Выделим стандартный размер (первые два), малый (вторая линия) и длинный (соответственно третья линия):
Отдельно взятый блок будет выглядеть так:
Аналогично отображаются другие блоки. (Меняем стили только внутренних элементов)
Переходим к footer
footer состоит из трех расположенных последовательно вложенных блоков:
1) Twitter
2) SiteMap
3) Social Networks
И четвертого, выровненного по правому краю — логотипу:
Разберем верстку каждого из этих блоков:
Состоит из времени, заголовка и текста.
В стилях задаем размер блока, цвета и прочие стили:
Здесь же задали и стили заголовков для остальных блоков (т.к. они одинаковы)
Sitemap
Карта сайта состоит из блоков-ссылок, для которых с помощью модификаторов убираем нижнее подчеркивание и красим в белый цвет.
Эффект 2 колонок получаем за счет указания размера блока + одной группе ссылок задаем float:left, другой float: right:
Social
Малые иконки от «стандартных» отличаются только модификатором, задающим размер.
Footer logo
Для лого в футере странице воспользуемся уже готовым блоком b-logo. Вставим данный блок внутрь элемента, который будет отформатирован с помощью float:right;
Подведем итог
В данном обучающем посте мной была поставлена задача показать, что использование методологий (таких как БЭМ) позволяет упростить разработку веб-страниц за счет «единого словаря терминологий» и единой структуры страницы.
Также, данный пост является дополнением моего комментария (в начале поста) в котором я говорил о том, почему использовать стили на id — есть bad practices.
БЭМ для начинающих. Очевидные и неочевидные вопросы верстки
Jan 18, 2018 · 15 min read
Эта статья написана по мотивам БЭМапа — митапа по БЭМ — с одноименным названием БЭМ для начинающих.
Нас часто спрашивают о верстке по БЭМ и про технологии, которые мы используем: почему нужно делать так, а не иначе? Зачем мы создали целый стек новых технологий, когда можно пользоваться готовыми? Зачем придумали такие длинные имена в классах?
На БЭМапе Владимир Гриненко дал ответы на эти вопросы. Мы решили сохранить их в статье.
Немного теории и практики:
Зачем вам БЭМ
БЭМ предоставляет единые п р авила создания и хранения кода, которые помогают масштабировать и повторно использовать код, увеличить производительность и упростить командную работу. Даже если вся ваша команда — это вы сами, БЭМ может быть вам полезен.
Основные почему
Не используем идентификаторы (ID селекторы)
ID определяет уникальное имя HTML-элемента. Если имя уникально, второй раз в интерфейсе его использовать не получится. Это мешает повторно использовать код.
1. ID обязателен для работы с JavaScript.
На практике современным браузерам не важно, с какими данными работать: ID или классами. Браузер одинаково быстро обрабатывает любой селектор.
Не используем селекторы тега
HTML-разметка страниц нестабильна: новый дизайн сайта может поменять вложенность разделов, уровень заголовоков (например, с
) или превратить абзац
Даже если дизайн не меняется, набор тегов ограничен. Чтобы использовать существующую верстку в другом проекте, придется решать конфликты стилей, написанных на одни и те же теги.
Расширенный набор семантических тегов также не может выразить все потребности верстки.
Например: в шапке страницы расположен логотип, по клику на который открывается главная страница сайта ( index ).
Чтобы отличать ссылку с логотипа от обычной ссылки в тексте, понадобятся дополнительные стили. Отменим подчеркивание и синий цвет для ссылки в логотипе:
Для тега отменять подчеркивание и синий цвет не нужно. Поэтому вынесем общие правила для ссылки в логотипе с разных страниц:
На первый взгляд, такой код имеет право на существование. Но представьте ситуацию, в которой дизайнер убирает логотип из макета. Такие имена селекторов не помогут понять, какие стили удалять из проекта вместе с логотипом. Селектор header a не показывает связь ссылки и логотипа. Такой селектор может принадлежать ссылке в меню шапки или, например, ссылке на профиль автора, а селектор header span может относиться вообще к любой части шапки.
Чтобы избежать путаницы, достаточно записать стили для логотипа с помощью селектора класса с именем logo :
Не используем общий сброс стилей (reset)
Общий сброс стилей — это глобальные CSS-правила, созданные для всей страницы. Они оказывают влияние на все узлы верстки, нарушают независимость компонентов и затрудняют их повторное использование.
В БЭМ не принято использовать «reset» и «normalize» даже для отдельно взятого блока.
Во время сброса или нормализации существующие стили отменяются, а затем подменяются другими, которые в процессе работы все равно приходится изменять и дорабатывать. В итоге разработчик вынужден писать стили, которые перекрывают то, что только что сбросили.
Не используем универсальный селектор (*)
Универсальный селектор сообщает, что в проекте создан стиль, который влияет на все узлы в верстке. Это накладывает ограничения на повторное использование верстки в другом проекте:
Кроме того, универсальный селектор может сделать код проекта непредсказуемым. Например, повлиять на стили компонентов из универсальной библиотеки.
Общие стили не выигрывают время: часто разработчик начинает с того, что сбрасывает все отступы для универсальных компонентов ( * < margin: 0; padding: 0; >), а потом все равно задает их как в макете (например, margin: 12px; padding: 30px; ).
Не используем вложенные селекторы
Вложенные селекторы увеличивают связность кода и затрудняют его повторное использование.
БЭМ не запрещает вложенные селекторы, но рекомендует не злоупотреблять ими.
Например, вложенность уместна, если нужно изменить стили элементов в зависимости от состояния блока или заданной темы:
Не используем комбинированные селекторы
Комбинированные селекторы имеют более высокую специфичность, чем одиночные, поэтому переопределять блоки становится сложнее.
Рассмотрим такой код:
Теперь добавим блоку модификатор active :
Если использовать простые селекторы классов, переопределение стилей не вызовет проблем:
Не совмещаем тег и класс в селекторе
Совмещение тега и класса (например, button.button ) повышает специфичность CSS-правил и затрудняет их переопределение.
Рассмотрим такой код:
И добавим блоку модификатор active :
Методология в редких случаях допускает объединение селекторов тега и класса, например, для стилизации комментариев в CMS-системах, которые не позволяют генерировать правильную разметку.
В комментарии пользователь может написать любой текст, вставить картинки или добавить свою разметку. Чтобы оставаться в рамках дизайна сайта, разработчик может заранее определить стили всех тегов, которые доступны пользователю, и применять их каскадом к вложенным блокам:
Не используем селекторы атрибутов
Селекторы атрибутов по информативности уступают селекторам классов. Чтобы доказать это, рассмотрим пример с формой поиска в шапке:
Воспользуемся селекторами атрибутов, чтобы записать стили для формы:
В таком примере по именам селекторов невозможно однозначно определить, что стили относятся к форме поиска. Нагляднее записать классами. В классах нет ограничений, чтобы писать понятно.
Можно записать, например, так:
Код стал более однозначным: теперь понятно, что стили относятся к форме, которая отвечает за поиск.
Но вложенность селекторов по-прежнему повышает специфичность CSS-правил и мешает безболезненно переносить верстку из проекта в проект. Чтобы избавиться от вложенности, воспользуемся принципами БЭМ.
Короткие выводы
Классы — единственный селектор, который позволяет изолировать стили каждого компонента в проекте, повысить читаемость кода и не ограничивать повторное использование верстки.
БЭМ. От теории к практике
Основы БЭМ
Методология БЭМ — это набор универсальных правил, которые можно применять независимо от используемых технологий, будь то CSS, Sass, HTML, JavaScript или React.
БЭМ помогает решить следующие задачи:
В БЭМ-проекте любой интерфейс делится на блоки, которые могут содержать элементы. Блоки — это независимые компоненты страницы. Элементы не существуют вне блока. Каждый элемент может принадлежать только одному блоку.
Именно блокам и элементам посвящены первые две буквы в аббревиатуре БЭМ.
Имя блока всегда уникально. Оно задает пространство имен для элементов и устанавливает видимую связь между всеми составляющими блока. Длинные, но понятные имена блоков и элементов позволяют определить связь между компонентами и не потерять составные части этих компонентов при переносе верстки.
Обратите внимание, что имя блока отделяется от имени элемента специальным разделителем. В классической схеме именования в БЭМ для разделителя используются два подчеркивания. Разделители могут быть любыми. Существуют альтернативные схемы, и каждый разработчик выбирает наиболее удобную для себя. Важно, чтобы разделители давали возможность на программном уровне отличать блоки от элементов и модификаторов.
Из имен селекторов очевидно, что для переноса формы в другой проект, необходимо скопировать все ее составляющие:
Запись имен в классах с помощью блоков и элементов решает еще одну важную проблему: избавляет от вложенности селекторов. У всех селекторов в БЭМ-проекте одинаковый вес. То есть переопределять стили, написанные по БЭМ, гораздо удобнее.
Теперь, чтобы использовать такую же форму в другом проекте, достаточно просто скопировать ее разметку и стили.
Суть именования компонентов в БЭМ в том, что в имени можно явно указать связь блока и его элементов.
Третья буква в аббревиатуре БЭМ
Официально буква «М» означает «модификатор», но негласно под нее попадает еще одно очень важное понятие в БЭМ — «микс». И модификаторы и миксы изменяют блок и его элементы. Давайте рассмотрим подробнее.
Модификатор определяет внешний вид, состояние и поведение блока либо элемента.
Наличие модификаторов опционально. Модификаторы позволяют комбинировать разные свойства блока, так как можно использовать неограниченное количество модификаторов. Но блоку или элементу нельзя одновременно присвоить разные значения одного и того же модификатора.
Разберемся, как работают модификаторы.
Предположим, в проекте нужна такая же форма поиска, которую мы рассмотрели выше. Она будет выполнять те же функции, но выглядеть по-другому (например, разный вид у форм поиска в шапке и в подвале страницы). Первое, что можно сделать, чтобы изменить внешний вид формы, написать дополнительные стили:
В БЭМ можно добавить блоку новые стили с помощью модификатора:
Форма может быть уникальна по разным показателям — цвету, размеру, типу, теме оформления. Все эти параметры можно задать с помощью модификатора:
Одна и та же форма может выглядеть по-разному и при этом быть одного размера:
При этом селекторы для каждого модификатора все равно будут иметь одинаковый вес:
Важно! Модификатор содержит только дополнительные стили, которые как-то изменяют исходную реализацию блока. Это позволяет один раз написать, как должен выглядеть универсальный блок, и добавить в стили модификатора только те свойства, которые отличают блок от его исходного вида.
Поэтому модификатор всегда должен находиться на одном DOM-узле с блоком или элементом, к которому он относится.
Модификатор позволяет получать очень частные случаи использования универсальных компонентов. При этом код блока или элемента не меняется, на DOM-узле просто создается нужная комбинация из модификаторов.
Микс позволяет одинаково форматировать разные HTML-элементы, совмещать поведение и стили нескольких сущностей без дублирования кода и решать задачи абстрактных блоков-оберток.
Миксом называется одновременное размещение нескольких БЭМ-сущностей (блоков, элементов, модификаторов) на одном DOM-узле.
Миксы, как и модификаторы, используются, чтобы изменять блоки. Разберем примеры, когда нужно применять миксы.
Можно вынести общие стили для таких блоков, но повторно использовать такой код не получится.
Рассмотрим, как можно создать семантически разные блоки с помощью микса на примере все той же формы:
Рассмотрим еще один пример, когда меняется семантика компонента. Для примера возьмем навигационное меню в шапке страницы, в котором все пункты должны быть ссылками:
1. Создать модификатор для пункта меню, который превратит пункт в ссылку:
2. Воспользоваться миксом универсального блока link и элемента item блока menu :
Внешняя геометрия и позиционирование. Отказываемся от абстрактных HTML-оберток
Миксы применяют, чтобы расположить один блок относительно другого или позиционировать элементы внутри блока.
В БЭМ стили, отвечающие за внешнюю геометрию и позиционирование, задаются через родительский блок.
Рассмотрим на примере универсального блока меню, который нужно разместить в шапке. В верстке блок меню должен отступать от родительского блока на 20px.
Существует несколько решений для этой задачи:
1. Написать стили с отступами самому блоку меню:
В таком случае блок menu перестанет быть универсальным. Если понадобится разместить меню в подвале страницы, придется править стили, потому что отступы скорее всего будут другими.
2. Создать модификатор для блока меню:
В таком случае в проекте появятся два типа меню, хотя это не так. Меню остается одно и то же.
3. Определить внешнее позиционирование блока — вложить блок menu в абстрактную обертку (например, блок wrap ), где задать все отступы:
Чтобы окончательно отказаться от соблазна создавать модификаторы и менять стили самого блока для позиционирования его на странице, нужно понять простую вещь:
Отступ от родительского блока — это не свойство вложенного блока быть с таким отступом. Это свойство родительского блока — знать, что вложенный в него блок должен отступать от границы на определенное количество пикселей.
4. Использовать микс. Знания про позиционирование вложенных блоков описываются в элементах родительского блока. Затем элемент родительского блока миксуется к вложенному блоку. В таком случае вложенный блок не специфицирует никакие отступы и может быть легко переиспользован в любом месте.
Продолжим рассматривать пример:
Элемент родительского блока (в нашем случае это header__menu ) полностью решает задачу абстрактных блоков-оберток, отвечающих за внешнее позиционирование блока.
Удобство параллельной разработки
В БЭМ любой макет делится на блоки. Благодаря тому, что блоки не зависят друг от друга напрямую, они могут разрабатываться параллельно разными разработчиками. Разработчик создает блок как универсальный компонент, который может быть переиспользован в любом другом проекте.
В качестве примера рассмотрим библиотеку блоков bem-components, которая содержит универсальные блоки, такие как ссылка, кнопка, поле ввода. Из универсальных компонентов легко создавать более сложные блоки. Например, селект или чекбокс.
Поблочная верстка проекта помогает сократить время на интеграцию кода разных разработчиков, гарантирует уникальность имен каждого компонента и позволяет тестировать блоки на стадии разработки.
Блоки в файловой структуре
Все БЭМ-проекты имеют схожую файловую структуру. Привычное для разработчиков расположение файлов облегчает навигацию по проекту, упрощает переключение между проектами и перенос блоков из одного проекта в другой.
Реализация каждого блока хранится в отдельной папке проекта. Каждой технологии (CSS, JavaScript, тестам, шаблонам, документации, картинкам) соответствует отдельный файл.
Код модификаторов и элементов также хранится в отдельных файлах блока. Такой подход позволяет подключать только те модификаторы и элементы, которые необходимы для данной реализации блока.
Чтобы улучшить навигацию в проекте, модификаторы блока со множественными значениями также можно объединять в отдельные директории.
Файловая структура любого БЭМ-проекта состоит из уровней переопределения. Уровни переопределения позволяют:
Поблочная разработка и хранение всех технологий блока в одной папке облегчает перенос блока из проекта в проект. Чтобы вместе с версткой перенести все стили и поведение блока, достаточно скопировать папку этого блока в новый проект.
Шаблонизация в БЭМ
В HTML разметка блока повторяется каждый раз, когда блок встречается на странице. Если разработчик пишет HTML вручную, исправлять ошибку или вносить дополнительные изменения необходимо в каждом экземпляре блока в разметке. Чтобы генерировать HTML-код и применять правки автоматически, в БЭМ используются шаблоны: блоки сами отвечают за то, как они будут представлены в HTML.
В БЭМ используется шаблонизатор bem-xjst, который содержит два движка:
Если шаблоны к блокам не написаны, шаблонизатор по умолчанию установит блокам тег
Сравните декларацию блоков и выходной результат HTML:
1. Меняем тег блока menu :
По аналогии с CSS, шаблон будет применен ко всем блокам menu на странице.
Шаблоны в БЭМ написаны на JavaScript, поэтому добавить новый элемент в шаблон также можно с помощью JavaScript:
3. Изменяем теги всем элементам inner и item :
5. Изменяем существующий шаблон. Правила в шаблонах применяются так же, как в CSS: нижнее правило перекрывает верхнее. Добавим новые правила в шаблон, изменим тег ссылкам с на :
Тестирование верстки
Протестировать работу всей страницы проблематично. Особенно в динамическом проекте, который связан с базой данных.
В БЭМ каждый блок покрывается тестами. Тесты — это такая же технология реализации блока, как JavaScript или CSS. Блоки тестируются на этапе разработки. Проще проверить правильность работы одного блока и потом собрать проект из гарантированно протестированных блоков. После этого останется только убедится, что обвязка для блоков работает правильно.
Сборка проекта
Сборка решает следующие задачи:
Чтобы включить в сборку только необходимые БЭМ-сущности, необходимо составить список блоков, элементов и модификаторов, используемых на странице. Такой список называется декларацией.
С чего начать?
Разработчики БЭМ создали шаблонный проект project-stub, в который по умолчанию подключены технологии и библиотеки БЭМ. Он содержит необходимый минимум конфигурационных файлов и директорий, чтобы быстро развернуть проект с нуля.