Работа с CSS. Методология БЭМ - slegarchik/slegarchik.github.io GitHub Wiki
https://ru.bem.info/methodology/quick-start
По данной методологии верстка осуществляется с помощью блоков div
. Стили блокам задаются с помощью атрибута class
. Имя класса формируется по определенным правилам. Методология не рекомендует использовать селекторы по тегам или id
.
- Группирующая часть разметки - содержит элементы, образующие единое целое; может содержать другие блоки
- Не следует задавать внешнюю геометрию - отступы, границы, параметры, влияющие на размеры и позиционирование
- Является независимым - поэтому может повторно использоваться и перемещать на странице
- Имя блока задает пространство имен, которое гарантирует зависимость элементов от блока (см. пример 1)
- Составная, но необязательная часть блока, которая не может использоваться без него
- Имя элемента соответствует схеме имя-блока__имя-элемента
- Не может быть частью другого элемента
- Может принадлежать только одному блоку
Пример 1
<div class="block">
<div class="block__elem1">
<div class="block__elem2">
<div class="block__elem3"></div>
</div>
</div>
</div>
Такая структура блока в методологии БЭМ представлена плоским списком элементов
.block {}
.block__elem1 {}
.block__elem2 {}
.block__elem3 {}
Это позволяет изменять DOM-структуру блока без внесения правок в коде каждого отдельного элемента
<div class="block">
<div class="block__elem1">
<div class="block__elem2"></div>
</div>
<div class="block__elem3"></div>
</div>
Cтруктура блока меняется, а правила для элементов и их названия остаются прежними
- Определяет внешний вид, состояние или поведение блока либо элемента
- Имя модификатора отделяется от имени блока или элемента одним подчеркиванием "_"
- Структура полного имени модификатора соответствует схеме имя-блока__имя-элемента_имя-модификатора_значение-модификатора
- Название модификатора характеризует внешний вид, например, «размер»: size_s, состояние («отключен»: disabled), «направление»: directions_left-top
- Модификатор нельзя использовать самостоятельно
- Совмещает поведение и стили нескольких сущностей без дублирования кода
- Создает семантически новые компоненты интерфейса на основе имеющихся
Пример 2
<!-- Блок `header` -->
<div class="header">
<!-- К блоку `search-form` примиксован элемент `search-form` блока `header`-->
<div class="search-form header__search-form"></div>
</div>
В данном примере было совмещено поведение и стили блока search-form и элемента search-form блока header. Такой подход позволяет задать внешнюю геометрию и позиционирование в элементе header__search-form, а сам блок search-form оставить универсальным. Таким образом, блок можно использовать в любом другом окружении, потому что он не специфицирует никакие отступы. Это позволяет говорить о его независимости.
- С целью многократного повторения миксом может быть вспомогательный класс
<article class="article text">...</article>
...
<footer class="footer">
<div class="copyright text">...</div>
</footer>
.text {
font-family: Arial, sans-serif;
font-size: 14px;
color: #000;
}
- Не следует совмещать теги и классы в селекторе. Объединение тега и класса (например,
button.button
) повышает специфичность CSS-правил, что усложняет задачу их переопределения - Не следует использовать комбинированные селекторы. Комбинированные селекторы (например,
.button.button_theme_islands
) имеют более высокую специфичность, чем одиночные селекторы, что усложняет задачу их переопределения - Стили, отвечающие за внешнюю геометрию и позиционирование, задаются не через родительский блок, а через элемент
Пример 3
<header class="header">
<button class="button header__button">...</button>
</header>
.button {
font-family: Arial, sans-serif;
text-align: center;
border: 1px solid black; /* Рамка */
}
.header__button {
margin: 30px; /* Отступ */
position: relative;
}
В данном примере внешняя геометрия и позиционирование блока button
задана через элемент header__button
. Блок button
не специфицирует никакие отступы и может быть легко переиспользован в любом месте.
- Разрабатывать новые CSS-реализации следует так, чтобы не пришлось менять уже существующие
Пример 4
<button class="button">...</button>
.button {
font-family: Arial, sans-serif;
text-align: center;
font-size: 11px;
line-height: 20px;
}
Предположим, что появилась необходимость изменить размер одной из кнопок. Следуя принципу открытости/закрытости, модифицируем кнопку
<button class="button">...</button>
<button class="button button_size_s">...</button>
.button {
font-family: Arial, sans-serif;
text-align: center;
font-size: 11px;
line-height: 20px;
}
.button_size_s {
font-size: 13px;
line-height: 24px;
}
- Принцип DRY - избегаем повторения кода для однотипных элементов
Пример 5. Использование микса
<body class="page">
<!-- верхний колонтитул и навигация -->
<header class="header page__header">...</header>
<!-- нижний колонтитул -->
<footer class="footer page__footer">...</footer>
</body>
.page__header {
padding: 20px;
}
.page__footer {
padding: 50px;
}
Блоки header
и footer
позиционируются на странице с помощью микса с элементами блока page
. Элементы page__header
и page__footer
опциональные и применяются к блоку page
, если необходимо разместить шапку (header
) или подвал (footer
) на странице. Блоки page
, header
и footer
остаются независимыми, так как не содержат стили позиционирования.
Пример 6. Использование дополнительного элемента
<button class="button">
<span class="button__inner">
<span class="icon"></span>
</span>
</button>
.button__inner {
margin: auto;
width: 10px;
}
Блок icon
позиционируется внутри универсальной кнопки с помощью стилей элемента button__inner