В этом уроке мы узнаем, как использовать PostCSS, чтобы сделать разработку CSS в стиле BEM / SUIT более простой и эффективной.
Эти две методологии разрабатывают соглашение об именах для классов, которое упрощает строгую функциональную ориентацию ваших стилей и помогает другим разработчикам распознавать назначение различных классов только по их названию.
БЭМ был предшественником этой методологии именования классов, созданной Яндексом. Методология SUIT — это подход, основанный на БЭМ, но с некоторыми изменениями и дополнениями, внесенными Николасом Галлахером. SUIT делает все, что делает BEM, но для многих пользователей это считается улучшением.
Работа с этими методами определенно помогает создавать лучший, более структурированный CSS. Однако, сложная часть заключается в том, что ручным вводом имен классов, необходимых в этой структуре, становится утомительно, и отслеживание того, как взаимосвязанные классы могут стать головной болью.
Плагин postcss-bem от Malte-Maurice Dreyer устраняет эти проблемы с помощью сочетания клавиш и вложения, которые вы научитесь использовать при прохождении этого урока.
Но сначала давайте кратко ознакомимся с методами BEM и SUIT, чтобы убедиться, что у вас есть четкое представление о преимуществах использования плагина postcss-bem и о том, как он используется.
Быстрый учебник по БЭМ
блок
В БЭМ блоках находятся высокоуровневые куски конструкции; строительные блоки, из которых сделан сайт. Блок должен быть частью вашего сайта, независимым от других частей, и теоретически может быть размещен в любом месте вашего макета, даже вложенным в другой блок.
Например, поисковая форма «блоки» на вашем сайте может использовать класс .search-form
.
Элемент
Элемент в БЭМ является подразделом внутри блока. Они обозначаются добавлением разделителя __
с двумя подчеркиваниями и имени элемента к имени родительского блока.
Например, форма поиска может включать заголовок, текстовое поле и элементы кнопки «Отправить». Их имена классов могут быть .search-form__heading
, .search-form__text-field
и .search-form__submit-button
соответственно.
Модификатор
Модификатор применяется к блоку или элементу для обозначения изменения его представления или изменения его состояния. Они обозначаются добавлением разделителя и имени модификатора к рассматриваемому блоку или элементу.
Официальные документы сайта БЭМ гласят, что разделители модификаторов должны быть одним подчеркиванием _
. Тем не менее, в «БЭМ-подобном» соглашении CSS Guidelines Гарри Робертса используются две черты --
и, вероятно, оно более широко используется и известно, чем официальное соглашение БЭМ.
Например, в дизайне может потребоваться представить формы расширенного поиска иначе, чем обычные формы поиска, и, следовательно, создать класс модификатора .search-form_advanced
(официальный BEM) или .search-form--advanced
(BEM-like).
В другом примере вам может потребоваться изменить внешний вид формы из-за изменения состояния, например, если недопустимое содержимое было только что отправлено, и, следовательно, создать модификатор .search-form_invalid
(официальный BEM) или .search-form--invalid
(БЭМ-подобный).
Быстрый учебник по костюму
SUIT включает в себя коммунальные услуги и компоненты . Внутри компонентов могут быть Модификаторы , Потомки и Состояния .
В SUIT используется комбинация паскаля (PascalCase), верблюда (camelCase) и тире. Его соглашения устанавливают ограничение на иногда запутанное количество черточек и подчеркиваний, которые могут появляться в БЭМ. Например, класс BEM .search-form__text-field
будет иметь вид .SearchForm-textField
в SUIT.
Утилита
Утилиты обрабатывают структуру и позиционное моделирование и написаны таким образом, что их можно применять в любом месте компонента. Они имеют префикс u-
и написаны в случае верблюда. Например, .u-clearFix
.
Компонент
Компонент в SUIT занимает место блока в BEM. Компоненты всегда пишутся в паскале и являются только частью SUIT, в которой используется паскаль, что делает их легко идентифицируемыми. Например, .SearchForm
.
Пространство имен компонентов
Компоненты могут опционально иметь префикс с пространством имен и одной чертой nmsp-
чтобы гарантировать предотвращение конфликтов, например .mine-SearchForm
.
происходящий
Потомок в SUIT заменяет элемент в BEM. Он использует одну черту -
и написано в случае верблюда. Например .SearchForm-heading
, .SearchForm-textField
и .SearchForm-submitButto
.
Модификатор
SUIT использует модификаторы, как и BEM, однако их роль более жестко контролируется. Модификатор SUIT обычно применяется только непосредственно к компоненту, а не к потомку. Его также не следует использовать для представления изменений состояний, поскольку SUIT имеет специальное соглашение об именах для состояний.
Модификаторы написаны в случае верблюда и начинаются с двух черточек --
. Например, .SearchForm--advanced
.
состояние
Классы состояний могут использоваться для отражения изменений в состоянии компонента. Это позволяет их четко отличать от модификаторов, которые отражают изменение базового вида компонента независимо от состояния. При необходимости, состояние также может быть применено к потомку.
Состояния имеют префикс is-
и пишутся в случае верблюда. Они также всегда пишутся как смежные классы. Например .SearchForm.is-invalid
.
Настройте свой проект
Теперь, когда у вас есть основы BEM и SUIT, пришло время настроить ваш проект.
Вам понадобится пустой проект с использованием Gulp или Grunt, в зависимости от ваших предпочтений. Если у вас еще нет предпочтений в отношении того или другого, я рекомендую использовать Gulp, так как вам потребуется меньше кода для достижения тех же целей, поэтому вам будет немного проще работать с ним.
О том, как настроить проекты Gulp или Grunt для PostCSS, вы можете прочитать в предыдущих уроках
соответственно.
Если вы не хотите вручную настраивать свой проект с нуля, вы можете загрузить исходные файлы, прикрепленные к этому учебному пособию , и извлечь предоставленный стартовый проект Gulp или Grunt в пустую папку проекта. Затем с помощью терминала или командной строки, указывающей на папку, выполните команду npm install
.
Установить плагины
Далее вам нужно установить плагин postcss-bem. Мы также установим плагин, который может работать с ним довольно хорошо: postcss-nested .
Используете ли вы Gulp или Grunt, выполните следующую команду в папке вашего проекта:
1
|
npm install postcss-bem postcss-nested —save-dev
|
Теперь мы готовы загрузить плагины в ваш проект.
Загрузка плагинов через Gulp
Если вы используете Gulp, добавьте эти переменные под переменными, уже имеющимися в файле:
1
2
|
var bem = require(‘postcss-bem’);
var nested = require(‘postcss-nested’);
|
Теперь добавьте каждое из этих новых имен переменных в ваш массив processors
:
1
2
3
4
|
var processors = [
bem,
nested
];
|
Проведите быструю проверку того, что все работает, запустив команду gulp css
проверив, что новый файл «style.css» появился в папке dest вашего проекта.
Загрузка плагинов через Grunt
Если вы используете Grunt, обновите объект processors
, который вложен в объект options
, следующим образом:
1
2
3
4
|
processors: [
require(‘postcss-bem’)(),
require(‘postcss-nested’)()
]
|
grunt postcss
быструю проверку того, что все работает, запустив команду grunt postcss
проверив, что новый файл style.css появился в папке dest вашего проекта.
Хорошо, ты готов к работе. Давайте узнаем, как генерировать структуру BEM и SUIT.
БЭМ и КОСТЮМ с postcss-bem
При написании кода вручную может возникнуть некоторая громоздкость в структуре BEM или SUIT, так как постоянное повторение одних и тех же идентификаторов в именах классов может стать утомительным, и отслеживание того, какие элементы и потомки принадлежат, какие блоки и компоненты могут запутаться.
Однако, когда вы используете postcss-bem, становится легко разобраться в структуре вашего кода, и повторение при наборе имен классов становится практически несуществующим.
Создание структуры SUIT
Несмотря на свое имя, по умолчанию postcss-bem будет выводиться в соответствии с синтаксисом SUIT, а не BEM. Вы можете выводить в синтаксисе БЭМ, который мы рассмотрим позже, но плагин в первую очередь предназначен для вывода SUIT, поэтому по этой причине мы начнем с синтаксиса SUIT.
Генерация компонента
Чтобы создать компонент, используйте синтаксис @component ComponentName {...}
.
Попробуйте это, добавив компонент SearchForm
в файл «src / style.css»:
1
2
3
4
|
@component SearchForm {
padding: 0;
margin: 0;
}
|
Скомпилируйте его, и ваш полученный код должен быть:
1
2
3
4
|
.SearchForm {
padding: 0;
margin: 0;
}
|
Генерация потомка
Чтобы создать потомок, используйте синтаксис @descendent descName {...}
вложенный в родительский компонент.
Добавьте потомок с именем textField
внутри вашего компонента SearchForm
следующим образом:
01
02
03
04
05
06
07
08
09
10
|
@component SearchForm {
padding: 0;
margin: 0;
/* Nest descendent under component */
@descendent textField {
border: 1px solid #ccc;
}
}
|
После компиляции вы должны увидеть:
1
2
3
4
5
6
7
8
|
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
|
Генерация модификатора
Создайте модификатор для компонента с синтаксисом @modifier name {...}
, вложенным в компонент, на который он воздействует. Модификаторы обычно следует размещать в верхней части вашего компонента, выше любых потомков и состояний.
Добавьте модификатор с именем advanced
в свой компонент SearchForm
со следующим кодом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@component SearchForm {
padding: 0;
margin: 0;
/* Typically, place modifiers above descendents */
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
}
}
|
Перекомпилируйте ваш код, и вы должны увидеть свой новый advanced
модификатор компонента:
01
02
03
04
05
06
07
08
09
10
11
12
|
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm—advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
|
Генерация государства
Состояния создаются с помощью синтаксиса @when name {...}
и могут быть вложены в компонент или потомок.
Добавьте состояние с именем invalid
для вашего textField
используя этот код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
/* This creates a state for the textField descendant */
@when invalid {
border: 1px solid red;
}
}
}
|
Теперь, когда вы скомпилируете свой код, вы увидите, что он содержит ваше новое invalid
состояние:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
.SearchForm {
padding: 0;
margin: 0;
}
.SearchForm—advanced {
padding: 1rem;
}
.SearchForm-textField {
border: 1px solid #ccc;
}
.SearchForm-textField.is-invalid {
border: 1px solid red;
}
|
Компоненты пространства имен
Вы можете именовать свои компоненты и все потомки, модификаторы и состояния, вложенные в них, окружая их @component-namespace name {...}
. Вы можете, если хотите, обернуть всю таблицу стилей этим пространством имен, чтобы все ваши классы автоматически имели префикс.
Попробуйте это, обернув весь свой код до сих пор с помощью @component-namespace mine {...}
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
@component-namespace mine {
@component SearchForm {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent textField {
border: 1px solid #ccc;
@when invalid {
border: 1px solid red;
}
}
}
}
|
После компиляции вы увидите, что теперь каждый из ваших компонентов имеет префикс mine-
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
.mine-SearchForm {
padding: 0;
margin: 0;
}
.mine-SearchForm—advanced {
padding: 1rem;
}
.mine-SearchForm-textField {
border: 1px solid #ccc;
}
.mine-SearchForm-textField.is-invalid {
border: 1px solid red;
}
|
Генерация утилиты
Утилиты создаются с использованием синтаксиса @utility utilityName {...}
. Вы помните, что при настройке своего проекта вы установили плагин, вложенный в postcss. Мы сделали это, так как это может быть очень удобно использовать в унисон с postcss-bem, как вы увидите в этом примере, где мы создаем утилиту clearFix
:
01
02
03
04
05
06
07
08
09
10
11
|
@utility clearFix {
&:before, &:after {
content: «»;
display: table;
}
&:after {
clear: both;
}
/* If supporting IE 6/7 */
*zoom: 1;
}
|
После добавления приведенного выше кода, скомпилируйте, и вы увидите, что эта новая утилита была создана:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
.u-clearFix {
/* If supporting IE 6/7 */
zoom: 1;
}
.u-clearFix:before, .u-clearFix:after {
content: «»;
display: table;
}
.u-clearFix:after {
clear: both;
}
|
Генерация БЭМ структуры
Чтобы активировать вывод синтаксиса BEM в postcss-bem, передайте style: 'bem'
опции style: 'bem'
в вашем Gulpfile или Gruntfile следующим образом:
01
02
03
04
05
06
07
08
09
10
11
|
/* Gulpfile */
var processors = [
bem({style: ‘bem’}),
nested
];
/* Gruntfile */
processors: [
require(‘postcss-bem’)({style: ‘bem’}),
require(‘postcss-nested’)()
]
|
По умолчанию postcss-bem будет использовать официальный разделитель для модификатора одиночного подчеркивания _
. Если для вашего проекта важно использовать более общий разделитель двух тире --
вместо этого вы можете изменить конфигурацию для плагина postcss-bem, перейдя в папку node_modules / postcss-bem вашего проекта, открыв index.js , найти строку 15 и изменить это:
1
2
3
4
5
6
7
|
bem: {
separators: {
namespace: ‘—‘,
descendent: ‘__’,
modifier: ‘_’
}
}
|
…к этому:
1
2
3
4
5
6
7
|
bem: {
separators: {
namespace: ‘_’,
descendent: ‘__’,
modifier: ‘—‘
}
}
|
Генерация блока
Поскольку «блок» в БЭМ коррелирует с «компонентом» в SUIT, используйте синтаксис @component block-name {...}
для генерации блока.
Чтобы создать блок search-form
добавьте этот код:
1
2
3
4
|
@component search-form {
padding: 0;
margin: 0;
}
|
Затем скомпилируйте и вы увидите:
1
2
3
4
|
.search-form {
padding: 0;
margin: 0;
}
|
Генерация элемента
Поскольку «элемент» в БЭМ соотносится с «потомком» в SUIT, они могут быть созданы с помощью синтаксиса @descendent element-name {...}
вложенного в родительский блок.
Чтобы создать элемент text-field
добавьте следующее:
1
2
3
4
5
6
7
8
9
|
@component search-form {
padding: 0;
margin: 0;
@descendent text-field {
border: 1px solid #ccc;
}
}
|
При компиляции вы увидите, что ваш новый элемент создан:
1
2
3
4
5
6
7
8
|
.search-form {
padding: 0;
margin: 0;
}
.search-form__text-field {
border: 1px solid #ccc;
}
|
Генерация модификатора
Несмотря на то, что BEM допускает модификаторы как для блоков, так и для элементов, плагин postcss-bem будет обрабатывать их, только если они вложены в блоки, а не в элементы, из-за соглашения SUIT о модификаторах, применяемых к компонентам, а не к потомкам. Они могут быть созданы с синтаксисом @modifier name {...}
, вложенным в его родительский блок.
Добавьте advanced
модификатор к вашему компоненту search-form
например так:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@component search-form {
padding: 0;
margin: 0;
@modifier advanced {
padding: 1rem;
}
@descendent text-field {
border: 1px solid #ccc;
}
}
|
И при компиляции это даст:
01
02
03
04
05
06
07
08
09
10
11
12
|
.search-form {
padding: 0;
margin: 0;
}
.search-form_advanced {
padding: 1rem;
}
.search-form__text-field {
border: 1px solid #ccc;
}
|
Нет коммунальных услуг или состояний, но есть пространства имен
В то время как в режиме @utility
синтаксис @utility
и @when
не будет компилироваться во что-либо, учитывая, что BEM не использует утилиты или состояния.
Однако, хотя он не является частью BEM, синтаксис @component-namespace
все равно будет работать, если вы захотите использовать его в своей таблице стилей BEM. Это будет префикс ваших классов с name--
:
01
02
03
04
05
06
07
08
09
10
11
12
|
.mine—search-form {
padding: 0;
margin: 0;
}
.mine—search-form_advanced {
padding: 1rem;
}
.mine—search-form__text-field {
border: 1px solid #ccc;
}
|
Давайте подведем итоги
Теперь вы знаете все о том, как ускорить разработку BEM и SUIT и упростить весь процесс. Давайте обобщим все, что мы рассмотрели:
- BEM и SUIT — это соглашения об именах классов, которые помогают ориентировать и организовывать функции таблиц стилей, а также помогают другим разработчикам распознавать назначение различных классов.
- SUIT похож на BEM, но с некоторыми дополнениями и изменениями
- Плагин postcss-bem предоставляет ярлыки для создания классов BEM и SUIT, таких как
@component
,@descendent
,@modifier
и т. Д. - Плагин также позволяет вкладывать код полезным способом, например, модификаторы вкладываются в компонент или блок, который они модифицируют.
- Пространство имен можно сделать автоматически, обернув классы
@component-namespace name {...}
В следующем уроке
Далее, мы рассмотрим еще один отличный способ воспользоваться преимуществами PostCSS, а именно — собрать инструментарий сокращений и ярлыков, которые мы можем использовать для ускорения и повышения эффективности нашего кодирования.
Увидимся там!