Блог экспериментатора инженера-разработчика: Infanty.
Я пишу how-to статьи на редкие темы или статьи обзоры - для себя и тех кто со мной работает.
Блог существует при поддержке: "Оккупационных сил Марса".

Интегрируем PostCSS и Bootstrap

Для того, что бы использовать БЭМ и стили Bootstrap совместно - необходимо что бы CSS классы приложения названные по методологии БЭМ наследовали стили CSS классов из Bootstrap (зачем - можно прочитать ниже: в разделе о БЭМ).

Копируем папку fonts из bootstrap в папку src проекта, а файл стилей bootstrap.css копируем в подпапку styles (папки src проекта). И исправляем @font-face { ... } в bootstrap.css:

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url('fonts/glyphicons-halflings-regular.eot');
  src: url('fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('fonts/glyphicons-halflings-regular.woff') format('woff'), url('fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
} 

После чего подключим bootstrap.css и CSS в которой будут необходимые CSS классы приложения - в main.css:

@import 'bootstrap.css';
@import 'styles-header.css'; 

А уже в styles-header.css, дадим PostCSS инструкцию по копированию необходимых CSS стилей из определённых классов bootstrap (например из img-circle) в нужные CSS классы приложения (например в logo-img):

.logo-img {
  @extend .img-circle;
} 

БЭМ

БЭМ расшифровывается как: Блок - Элемент - Модификатор. Данная методология применяется для именования CSS классов. По данной методологии всю HTML страницу можно разбить на независимые логические блоки. Например: шапка или подвал сайта (разбиение аналогично компонентам React.js приложения, БЭМ нужна для правильного наименования CSS классов компонентов React.js приложения).

При этом в один блок могут быть вложены как элементы (например: логотип и название сайта в шапке), так и другие блоки (например: блок поиска - с поисковой строкой и кнопкой поиска, в шапке сайта). Важно, что - CSS вёрстка вложенного блока не должна быть привязана к классу родительского блока (что бы его можно было пере-использовать в другом месте).

У блока или элемента, помимо базового CSS класса, может быть одновременно несколько CSS классов-модификаторов. Например код блока для изображения выше, может быть таким:

<ul class="menu-header">
  <li class="menu-header__item">Tab 1</li>
  <li class="menu-header__item menu-header__item--current">Tab 2</li>
  <li class="menu-header__item">Tab 3</li>
  <li class="menu-header__item">Tab 4</li>
</ul> 

Где:

  • menu-header - CSS-класс блока.
  • menu-header__item - CSS-класс элемента.
  • menu-header__item--current - CSS-класс модификатора элемента или блока.

Что делать с "внучатыми" селекторами? БЭМ расшифровывается как Блок_Элемент--Модификатор, а не Блок__Элемент__Элемент--Модификатор. Поэтому не будем создавать классы вида: "card__header__title" и "card__body__text__link".

Пример вёрстки блока по БЭМ

Рассмотрим пример наименования CSS классов по методологии БЭМ для определённой части макета страницы: "корзины покупателя". При этом условимся, что все элементы корзины, кроме кнопки "Click me!" - больше не используются в макете.

<div class="card">
  <!-- В блок: card, вложен блок: card__header. -->
  <div class="card__header">
    <h2 class="card__title">Title text here</h2>
  </div>

  <div class="card__body">
    <img class="card__img" src="http://some-img.png" alt="description">
    <p class="card__text">Lorem ipsum dolor sit amet, consectetur</p>
    <p class="card__text">Adipiscing elit.
      <a href="/somelink.html" class="card__link">Pellentesque amet</a>
    </p>

    <!-- Данная кнопка является блоком используемым за пределами блока: card. -->
    <!-- Данная кнопка содержит 2 модификатора. -->
    <button class="button button--right button--small">Click me!</button>
  </div>
</div>
 

Примечания по данному примеру:

  • Так как все элементы корзины, кроме кнопки "Click me!" - больше не используются в макете (других местах макета), то даже вложенные блоки и их элементы - стоит называть начиная с префикса: card. Это позволит объединить код стилей для CSS классов данного блока (а так же вложенных блоков и всех элементов) в один файл используя PostCSS.
  • Так как кнопка "Click me!" будет использоваться (как вложенный блок) и в других частях макета страницы, то класс кнопки будет именоваться: button, а не card__button.
  • Добавлять кнопке модификатор: button--right - стоит только, если в макете страницы имеется несколько таких же кнопок но без выравнивания. Т.е. если в ожидаемом поведении от блока кнопки - отсутствует выравнивание и необходимо создать кнопку с выравниванием, то тогда стоит создать отдельный модификатор для выравнивания кнопки. При условии, что модификатор переопределяет менее 40% CSS стилей изначальной кнопки (иначе стоит создать новый CSS класс содержащий свои стили).
  • Если бы кнопка "Click me!" была одна единственная в макете, то её CSS класс именовался бы: card__button.
  • Если бы все кнопки "Click me!" (т.е. их бы было больше одной) в макете - были бы выровнены по правому краю, то не имело бы смысл создавать отдельно CSS класс и модификатор, эти CSS стили были бы объеденены в один CSS класс.
  • Так как БЭМ предписывает разделять единый CSS файл стилей, на файлы где ключевым блокам - соответствует свой CSS файл стилей. При этом в этом CSS файле содержатся стили для всех элементов ключевого блока и вложенных блоков которые неповторяются в других местах макета. В таком случае CSS файл для всех стилей примера - будет называться card.css и содержать следующий код:
.card {
  ...

  &__header {
    ...
  }

  &__title {
    ...
  }

 ...
 ...
 ...
} 

После обработки, PostCSS сформирует CSS следующего содержания:

.card {
  ...
} 

.card__header {
  ...
}

.card__title {
  ...
}

 ...
 ...
 ...

В итоге используя PostCSS и БЭМ:

  • произведём именование CSS классов для всех блоков и элементов страницы;
  • создадим файлы CSS стилей для ключевых блоков: header.css, body.css, card.css, footer.css и т.п. в папке: src/styles;
  • создадим отдельный CSS файл для переменных цвета используемых в CSS стилях для ключевых блоков (используя функционал PostCSS);
  • объеденим все CSS файлы в main.css используя: @import, как в статье: "Добавление в React.js приложение - SASS подобной вёрстки, используя PostCSS".