БЭМ нейминг для HTML верстки сайтов
Какую задачу решает БЭМ нейминг
Если давать имена CSS классам не задумываясь, то вскоре можно обнаружить в проекте такие имена как text-1, text-2 и text-3. Или например button-1, button-2 и так далее. Чем больше растет проект и чем чаще в проекте встречаются похожие, но с небольшими различиями элементы, тем сложнее придумать им название так чтобы в названиях CSS классов можно было легко ориентироваться. БЭМ нейминг решает эту задачу.
Сразу отмечу что методология это рекомендации к тому как придумывать CSS имена. Нарушение методологии не приведет к технической ошибке, однако ухудшит читаемость вашего кода другими специалистами верстальщиками.
Идея БЭМ нейминга состоит в том чтобы с помощью имен CSS классов определить независимые блоки, обозначить их элементы и определить возможные модификации. Рассмотрим подробнее.
Примечание
В данной статье описывается альтернативный синтаксис БЭМ нейминга, который называется Two Dashes. Этот стиль визуально более выразителен и легче воспринимается для чтения. Описание стиля Two Dashes в официальной документации.
Правила формирования имен классов в БЭМ нейминге
- Имена записываются латиницей в нижнем регистре.
- В имени классов используются полные слова, без сокращений.
- Для разделения слов в именах БЭМ-сущностей используется дефис (-).
- Имя элемента отделяется от имени блока двумя подчеркиваниями (__).
- Модификаторы отделяются от имения блока или элемента двумя дефисами (--).
Пример именования по БЭМ неймингу:
.block /* Блок */ .block__element /* Элемент */ .block--modifier /* Модификатор для Блока*/ .block__element--modifier /* Модификатор для Элемента */
Основные понятия БЭМ нейминга
Блоки
Блок — это независимый самодостаточный элемент страницы. Простой тест на то можно ли определить элемент как блок. Блок можно вырвать с его места расположения на странице и разместить на абсолютно чистую страницу, при этом он не потеряет своей актуальности, будет понятно о чем он и какой контент в нем представлен, он не утратит своего смысла.
Классическим вариантом блока является карточка товара, карточка со статьей, отдельно секция с товаром или со статьей, шапка, подвал, и другие секции или целостные элементы страницы.
Имя для блока описывается одним или несколькими словами. Несколько слов в имени блока разделяются дефисом -.
Имя блока пишется строчными буквами, не имеет заглавных. В имени используются полные слова, без сокращений.
Неправильно:
product_card productCard ProductCaRD s-products btnPrimary Card
Правильно:
product-card section-products header footer button card
Элементы
Элемент — это составная часть блока. Элемент является частью блока и находится внутри него.
Если мы рассмотрим блок карточки с товаром, то его внутренние составные части это и есть элементы данного блока. Например элементами карточки с товаром будут: заголовок карточки, цена, изображение товара, описание товара, кнопка покупки.
Элементы всегда принадлежать какому-либо блоку. Не бывает независимых элементов. Принадлежность элемента к блоку описывается двойным подчеркиванием __ . В имени элемента всегда вначале указывается имя блока к которому он принадлежит, далее после двойного подчеркивания идет имя элемента. block__element
Рассмотрим пример с элементами внутри карточки.
Неправильно:
card-title cardPrice card_description card--button
Правильно:
card__title card__price card__description card__button
Модификаторы
Модификатор — это дополнительный класс который добавляется к html тегу с блоком или элементом. Модификатор — модифицирует (изменяет) отображение блока на странице. Модификатор не может использоваться на теге отдельно от блока или элемента.
Имя класса модификатора содержит в себе имя блока или элемента для которого он создается, далее идет разделитель в виде двух дефисов --, и в конце имя модификатора.
Например у нас есть блок карточки товара card, и нужно сделать модификатор для карточки товара по распродаже, который будет менять ее фон. Имя такого модификатора будет следующее: card--sale
Давайте придумаем модификатор для элемента. Например в карточке товара есть его цена. Цена это элемент блока card и имеет класс card__price . Модификатором для такого элемента будет класс card__price--sale, в котором мы сначала повторяем имя элемента, далее после двойного дефиса указываем имя модификатора.
Неправильные имена модификаторов:
card_sale card-sale cardSale sale
Правильные имена модификаторов:
card--sale cart__price--sale
Использование модификаторов
Модификатор всегда применяется к блоку или элементу. Нельзя использовать на теге только модификатор, без класса блока или элемента.
Неправильное использование модификаторов:
<div class="card--sale"> <div class="card__price--sale">12000 РУБ</div> </div>
Правильное использование модификаторов:
<div class="card card--sale"> <div class="card__price card__price--sale">12000 РУБ</div> </div>
Выводы и пример разметки с БЭМ неймингом
Пример карточки с товаром. Блок — это карточка, её элементы это изображение, название, цена и ссылка «подробнее».
<div class="card"> <img class="card__img" src="img/apple-watch.jpg"> <h3 class="card__title">Apple Watch</h3> <span class="card__price">12000 РУБ</span> <a class="card__read-more" href="#">Подробнее</a> </div>
Пример карточки с товаром с модификатором. Модификатор sale установлен для блока карточки и для элемента с ценой.
<div class="card card--sale"> <img class="card__img" src="img/apple-watch.jpg"> <h3 class="card__title">Apple Watch</h3> <span class="card__price card-price--sale">12000 РУБ</span> <a class="card__read-more" href="#">Подробнее</a> </div>
Пример карточки с вложенными элементами. Зачастую вам могу потребоваться дополнительные обертки внутри блока. Они также будут являться его элементами. Важно помнить все элементы внутри блока принадлежат непосредственном этому блоку. Даже если они вложены друг в друга. Не бывает элементов от элементов. Элементы бывают только от блока.
Вложенность в БЭМ нейминге
Блоки. Блоки могут быть вложены друг в друга.
Элементы. Элемент который принадлежит к блоку может находится только в нем. Элемент не может находится за пределами блока к которому он принадлежит.
Элементы одного блока могут находится друг в друге. Элементы можно вкладывать друг в друга, потому как всегда могут понадобиться дополнительные обертки и структурные элементы.
Важно помнить, все элементы внутри блока принадлежат непосредственном этому блоку. Даже если они вложены друг в друга. Не бывает элементов от элементов! Элементы бывают только от блока.
Неправильно:
<div class="card"> ... <div class="card__details"> <div class="card__details__price">12000 РУБ</div> <a class="card__details__reade-more" href="#">Подробнее</a> </div> </div>
Правильно:
<div class="card"> ... <div class="card__details"> <div class="card__price">12000 РУБ</div> <a class="card__reade-more" href="#">Подробнее</a> </div> </div>
Несмотря на то что price и read-more вложены в details, они все равно являются элементами от блока card.
Исключения
Зачастую кнопки определяют отдельными блоками. Идея в том что кнопка может присутствовать на разных страницах и в разных блоках страницы, поэтому для поддержания ее единых стилей, и избежания дублирования кода, чтобы не описывать одну и ту же кнопку как несколько элементов в разных блоках.
Когда в проекте есть дизайн система, то в блоки могут быть вынесены заголовки и другие элементы дизайн системы которые одинаковы на всех страницах. На первых порах изучения бем нейминга рекомендуем ограничиться вынесением в блоки только кнопок и одинаковых заголовков.
Пример кода с вынесением в блоки кнопок и заголовков.
Пример блока карточки товара. Кнопка — отдельный блок.
<div class="card"> <img class="card__img" src="img/apple-watch.jpg"> <h3 class="card__title">Apple Watch</h3> <div class="card__details"> <div class="card__details__price">12000 РУБ</div> <a class="button" href="#">Подробнее</a> </div> </div>
Пример блока секции. Заголовок header — отдельный блок. Карточки card и пагинация pagination — также отдельные блоки.
<div class="section"> <div class="section__header"> <div class="header">Заголовок</div> </div> <div class="section__cards"> <div class="card">...</div> <div class="card">...</div> <div class="card">...</div> </div> <div class="section__pagination"> <div class="pagination"> <a class="pagination__item">1</a> <a class="pagination__item">2</a> <a class="pagination__item">3</a> </div> </div> </div>
Ссылки
Официальная документация по БЭМ нейминг: https://ru.bem.info/methodology/quick-start/