Работа с 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) на странице. Блоки pageheader и footer остаются независимыми, так как не содержат стили позиционирования.

Пример 6. Использование дополнительного элемента

	<button class="button">
           <span class="button__inner">
              <span class="icon"></span>
           </span>
        </button>
	.button__inner {
           margin: auto;
           width: 10px;
        }

Блок icon позиционируется внутри универсальной кнопки с помощью стилей элемента button__inner

⚠️ **GitHub.com Fallback** ⚠️