Препроцессоры и современный тулинг
Сравниваем инструменты, которые надстраиваются над CSS: препроцессор Sass, постпроцессор PostCSS, utility-first c Tailwind и CSS Modules — и разбираемся, что и когда уместно.
Препроцессор — это инструмент, который превращает расширенный синтаксис (Sass/SCSS) в обычный CSS на этапе сборки. Браузер видит уже готовый CSS — про Sass он ничего не знает.
Голый CSS многое умеет, но на больших проектах хочется переменных-вычислений, переиспользуемых кусков и автоматической рутины (префиксы, минификация). Этим занимается слой тулинга. Важно различать препроцессоры (работают до CSS, добавляют синтаксис) и постпроцессоры (работают над готовым CSS, преобразуют его).
Зачем это на практике
Тулинг убирает ручную рутину и дублирование. Без него вы вручную дописываете вендорные префиксы, копируете один и тот же блок свойств в десять мест, держите цвета строками. Sass даёт миксины и вложенность, PostCSS автоматически проставляет префиксы под нужные браузеры, Tailwind избавляет от придумывания имён классов, CSS Modules гарантируют, что классы компонента ни с чем не столкнутся. Каждый инструмент закрывает свою боль — и выбирать их стоит осознанно.
Sass/SCSS: переменные, вложенность, миксины
Sass — самый известный препроцессор. Современный синтаксис — SCSS: это надмножество CSS (любой валидный CSS — валидный SCSS), поэтому порог входа низкий. Ключевые возможности:
Переменные и вложенность
$primary: #3b82f6;
$radius: 8px;
.card {
border-radius: $radius;
background: #fff;
// вложенность: & — ссылка на родителя (.card)
&__title { font-size: 1.25rem; }
&--featured { border: 2px solid $primary; }
&:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
}
Символ & внутри вложенного блока означает «родительский селектор». Запись &__title внутри .card скомпилируется в .card__title — удобно для BEM. Это сахар записи: на выходе получаются обычные плоские селекторы.
Миксины — переиспользуемые блоки
Миксин — именованный набор объявлений, который можно подставлять с параметрами:
@mixin flex-center($gap: 0) {
display: flex;
align-items: center;
justify-content: center;
gap: $gap;
}
.toolbar { @include flex-center(12px); }
.modal__footer { @include flex-center; }
Компилируется в:
.toolbar {
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
}
Важно помнить: переменные Sass — это сборочное время. Они подставляются в значения при компиляции и в браузере не существуют. Для рантайм-тем (предыдущий урок) нужны CSS-переменные, а не Sass-переменные — это разные инструменты для разных задач, и их часто используют вместе.
PostCSS и автопрефиксы
PostCSS — это не язык, а платформа плагинов, обрабатывающая уже готовый CSS. Сам по себе он почти ничего не делает; всё решают подключённые плагины. Самый известный — Autoprefixer: он смотрит на ваш список поддерживаемых браузеров (browserslist) и сам дописывает нужные вендорные префиксы.
/* вы пишете чистый стандарт */
.box { user-select: none; }
/* Autoprefixer на выходе добавит то, что требуется браузерам из browserslist */
.box { -webkit-user-select: none; user-select: none; }
Другие популярные плагины: postcss-preset-env (даёт писать ещё не везде поддержанный синтаксис будущего CSS), минификатор cssnano, импорт файлов. Многие сборщики (и Tailwind) под капотом устроены как раз на PostCSS.
Utility-first и Tailwind как подход
Tailwind переворачивает идею «семантических классов» (как BEM) с ног на голову. Вместо того чтобы писать .card и описывать его в CSS, вы собираете внешний вид прямо в разметке из готовых утилитарных классов, каждый из которых отвечает за одно свойство:
<article class="rounded-lg bg-white p-4 shadow flex items-center gap-3">
<h3 class="text-lg font-semibold">Тариф Pro</h3>
</article>
Здесь p-4 — это padding, rounded-lg — скругление, flex — display. CSS вы почти не пишете. Плюсы: не нужно придумывать имена, стили не «протекают» между компонентами, значения берутся из единой шкалы (фактически встроенные дизайн-токены), а неиспользуемые классы вырезаются из финального бандла. Минусы: разметка «шумная», длинные строки классов, и часть людей считает это смешением представления с содержимым. Tailwind хорош там, где много уникальной верстки и важна скорость; BEM — там, где нужны строго переиспользуемые именованные компоненты. Это конкурирующие философии, а не «лучше/хуже».
CSS Modules — локальная область видимости
CSS Modules решают узкую, но важную задачу: изоляцию имён классов. Вы пишете обычный CSS в файле Card.module.css, а сборщик при импорте превращает каждое имя класса в гарантированно уникальное (например, title → Card_title_a3f9). Коллизии между компонентами становятся невозможны технически — то, что BEM делает дисциплиной имён, CSS Modules делают автоматикой.
/* Card.module.css — пишем простые имена, изоляцию даст сборщик */
.title { font-size: 1.25rem; }
.featured { border: 2px solid #3b82f6; }
В компоненте вы импортируете объект со стилями и подставляете сгенерированные имена. CSS Modules особенно естественны в компонентных фреймворках (React и подобные), где каждый компонент держит свой CSS рядом.
Как это работает под капотом
Объединяет все четыре инструмента одно: они работают на этапе сборки, а в браузер уезжает обычный CSS. Sass компилирует SCSS в CSS, разворачивая вложенность и миксины в плоские правила и подставляя значения переменных. PostCSS трансформирует уже готовый CSS, прогоняя его через цепочку плагинов (как middleware). Tailwind сканирует разметку, оставляет в бандле только реально использованные утилиты и выкидывает остальные тысячи. CSS Modules переименовывают классы при импорте и отдают компоненту карту «исходное имя → уникальное». Браузер ни про Sass, ни про модули не знает — он получает финальный плоский CSS. Поэтому все эти инструменты можно комбинировать: например, SCSS + PostCSS-автопрефиксы + CSS Modules в одном проекте.
Частые ошибки
- Глубокая вложенность в Sass. Соблазн писать
.a { .b { .c { ... } } }приводит к раздутой специфичности на выходе — ровно той проблеме, от которой спасает BEM. Вкладывайте на 1–2 уровня, чаще через&для модификаторов. - Ждут, что Sass-переменные дадут темы в рантайме. Они вычисляются при сборке. Переключаемые темы — это CSS-кастомные свойства; Sass и CSS-переменные решают разные задачи.
- Ставят PostCSS «чтобы было», без плагинов. Чистый PostCSS бесполезен — пользу приносят конкретные плагины (Autoprefixer и т.п.) и настроенный browserslist под ваши браузеры.
- Выбирают инструмент по моде, а не по задаче. Tailwind не «лучше» BEM, CSS Modules не «лучше» Sass — у каждого своя ниша. Реальные проекты часто комбинируют их.
- Дублируют систему значений. Если уже есть дизайн-токены на CSS-переменных, не заводите параллельно те же значения Sass-переменными — будет два расходящихся источника правды.
Итоги
- Препроцессор (Sass/SCSS) добавляет синтаксис до CSS: переменные, вложенность (
&— родитель), миксины (@mixin/@include); компилируется в плоский CSS. - PostCSS — платформа плагинов над готовым CSS; ключевой плагин Autoprefixer проставляет вендорные префиксы по browserslist.
- Tailwind (utility-first) собирает вид из мелких утилитарных классов прямо в разметке — конкурирующая с BEM философия, не «замена».
- CSS Modules автоматически делают имена классов уникальными — изоляция компонентов через сборку, а не через дисциплину.
- Все эти инструменты работают на этапе сборки и выдают обычный CSS, поэтому свободно комбинируются; выбор — по задаче, а не по моде.