2 posts tagged

препроцессоры

Нужны ли CSS-препроцессоры в 2018 году, или насколько мы близки к ванильному CSS

Среди разработчиков сейчас есть тенденция отказа от препроцессоров в пользу ванильного CSS. Давайте разберёмся, готова ли веб-платформа полностью заменить препроцессоры.

Начнём с того, что классические препроцессоры вроде Sass/Less/Stylus свой век почти отжили — им на смену пришли современные возможности CSS, а также PostCSS с большой экосистемой плагинов. PostCSS по сути тоже препроцессор, только модульный — это главная причина его популярности и нужности. Подключаете и используете только нужные плагины, а если нужно что-то нестандартное, всегда можно написать свой плагин.

Окей, классические препроцессоры остались в прошлом, и теперь мы наедине с ванильным CSS и PostCSS. Большинство разработчиков на этом и останавливаются — мигрируют с классических препроцессоров на PostCSS, пишут стили в синтаксисе, максимально близком к нативному (и это хорошо, нечего плодить разные синтаксисы), а для поддержки недостающих возможностей подключают плагины.

В идеале хотелось бы избавиться от PostCSS и оставить только ванильный CSS (#usetheplatform). Как дела с ключевыми возможностями препроцессоров в веб-платформе?

Математические выражения. Поддерживаются нативно в виде функции calc() в CSS. Более того, calc() поддерживается подавляющим большинством браузеров — проблемы есть только в IE9-, Android Browser 4.3- и Opera Mini. Есть плагин postcss-calc, заранее вычисляющий на этапе сборки всё, что можно.

Переменные. Реализованы в CSS в виде кастомных свойств, и имеют даже более мощную функциональность, чем в препроцессорах — они доступны в JS, а также могут менять свои значения динамически с помощью медиавыражений:

:root {
  --base-font-size: 16px;
}

@media (min-width: 1280px) {
  :root {
    --base-font-size: 18px;
  }
}

Кастомные свойства не поддерживаются в IE 11- и в большинстве мобильных браузеров. Базовая функциональность кастомных свойств реализуется плагином postcss-custom-properties — он на этапе сборки вычисляет все значения переменных и подставляет их в места использования, на выходе получается обычный CSS-файл с захардкоженными значениями. Динамическое переопределение значений переменных в медиавыражениях плагином не поддерживается.

Вложенность. Есть черновик Таба Аткинса с предложением по добавлению вложенности в CSS, но о полноценной спецификации и поддержке браузерами задумываться, судя по всему, сильно рано. И, на мой взгляд, вложенность в CSS должна поддерживаться только для медиавыражений, чтобы не дублировать селекторы, то есть предыдущий пример я бы хотел написать так:

:root {
  --base-font-size: 16px;

  @media (min-width: 1280px) {
    --base-font-size: 18px;
  }
}

Вложенность селекторов, на мой взгляд, не нужна, потому что она поощряет увеличение специфичности и затрудняет чтение кода.

Примеси (миксины). И здесь не обошлось без черновика Таба Аткинса. Его предложение заключалось в том, чтобы реиспользовать функциональность кастомных свойств и разрешить хранить в них не только значения, но и целые блок стилей, а затем применять эти блоки с помощью нового правила @apply:

.popup {
  --heading-style: {
    font-weight: bold;
    text-transform: uppercase;
  }
}

.popup__title {
  @apply(--heading-style);
}

На первый взгляд круто, но в таком решении есть проблемы из-за смешения обычных переменных, используемых через var(), и блоков правил, используемых через @apply() — Таб Аткинс подробно описал эти проблемы и сразу же предложил новое решение на основе Shadow DOM — псевдоэлемент ::part(). Из статьи с описанием проблем мне стало ясно, что у Таба изначально было немного другое видение предназначения примесей.

Таб заметил, что кастомные свойства не дают достаточно гибкости для стилизации веб-компонентов. В качестве примера рассмотрим попап — изолированный компонент, к внутренностям которого доступ мы не имеем. Кастомные свойства позволяют настроить внешний вид попапа, например задать цвет его подложки или размер заголовка. Ограничение в том, что внешний пользователь компонента не может доопределить или переопределить стили его частей — например, того же заголовка. Именно эту задачу Таб решил, предложив @apply, и, к счастью, пришёл к лучшему решению с ::part().

Вроде здорово, но есть проблема. Основная задача, которую решают примеси — не до- или переопределение стилей, а абстракция. Есть замечательная статья, объясняющая, что CSS — неэффективный язык, потому что в нём нет средств абстракции и комбинирования. Примеси в первую очередь полезны для абстрагирования стилей и комбинирования этих абстракций. Только примеси позволяют добиться настоящего разделения разметки и стилей:

Разделение разметки и стилей с помощью примесей

В общем, так как Таба Аткинса унесло в другую степь, перспектива появления примесей в CSS пока что туманна.

Итого

Из трёх ключевых возможностей (переменные, вложенность, примеси) в CSS реализована только одна — переменные, и то поддержка браузерами пока не позволяет их использовать.

В простых проектах можно начать использовать только нативные возможности CSS с PostCSS-плагинами, выступающими в роли полифилов на этапе сборки. Такой подход я попробовал на одном из проектов. Нужно было сверстать небольшой лендинг. Все стили я написал в одном файле с использованием CSS-переменных, причём на время разработки даже не пришлось настраивать никакую сборку — было достаточно подключить в разметке исходный файл со стилями, Хром нативно поддерживает CSS-переменные. Сборка потребовалась только для вычисления переменных, простановки вендорных префиксов и минификации — это заняло всего 17 строчек кода.

В серьёзных проектах такой подход скорее всего покажет себя плохо. Отсутствие вложенности и примесей как средства абстракции сильно усложняет поддержку кода, поэтому эту нишу препроцессоры занимают прочно.


Подписывайтесь на мой канал в Телеграме: публикую анонсы новых статей, заметки о фронтенде и полезные материалы.

Jan 8   css   вёрстка   препроцессоры   фронтенд

Зачем нужен PostCSS

Когда я публикую в FW какой-либо материал о PostCSS, в комментариях сразу начинается срач в духе «да зачем вообще нужен этот PostCSS, есть же препроцессоры!», «PostCSS вообще лажа, не понимаю, почему вокруг него подняли такой шум». Все эти комментарии пишут люди, до конца не понимающие суть задач, которые должен решать PostCSS. Однако каждый из них спешит поделиться своим мнением и рассказать всему миру, что PostCSS — это какая-то ненужная дичь, которую нам пытаются тщательным образом впарить. В этой заметке я попробую «на пальцах» объяснить, чем PostCSS лучше препроцессоров и вообще зачем он нужен.

Также читайте моё интервью с Андреем Ситником, в котором мы поговорили об истории создания PostCSS, применении PostCSS в разработке и о планах проекта на будущее.

На самом деле всё довольно просто. Почему появились препроцессоры? Разработчикам не хватало возможностей, предусмотренных спецификацией CSS. Никто не любит выполнять рутинную работу, и верстальщики — не исключение. Препроцессоры дают нам замечательные возможности по ускорению и упрощению написания CSS: это переменные, вложенные блоки кода, инклуды, примеси и многое другое. Всё вроде бы круто, но проблема в том, что набор возможностей препроцессоров фактически перестал пополняться. Что год назад, что сейчас мы используем одни те же возможности препроцессоров. Развития никакого нет. Более того, все основные препроцессоры (Sass/Less/Stylus) по большему счёту ничем и не отличаются, кроме синтаксиса. Готов поспорить, что через год в препроцессорах не появится ничего принципиально нового.

Если мыслить в плоскости препроцессоров, то мы достигли вершины возможностей. Но PostCSS кардинально отличается от препроцессоров. Нельзя сравнивать PostCSS и препроцессоры, рассматривая PostCSS как ещё один препроцессор.

Что такое PostCSS? Это парсер. Просто парсер стилей. Он ничего не делает кроме того, что получает на входе написанные вами стили и разбирает их на составляющие, а затем собирает обратно. Вот между этими двумя этапами вклиниваются плагины для PostCSS, которые и выполняют всю полезную работу.

PostCSS создан для того, чтобы преобразовывать стили нужным нам образом. Преобразованием стилей занимаются плагины. Плагин берёт разобранный на составляющие код, который ему передал PostCSS, и как-то его обрабатывает. Самый простой пример, знакомый всем — это Автопрефиксер. Он получает на входе ваши стили, ищет в них плохо поддерживаемые свойства. Как только он находит такое свойство — скажем, display: flex; — он идёт на caniuse.com и ищет информацию о том, какие браузеры понимают это свойство только с префиксами. Если вы изначально указали в настройках, что вам нужно поддерживать эти браузеры, он добавляет в ваши стили то же самое свойство display: flex, но уже с нужными префиксами. Далее он обратно передаёт модифицированный код в PostCSS, и тот собирает его обратно в обычный CSS. Такова суть работы плагинов.

Если препроцессоры предоставляют нам строго ограниченный набор возможностей, то PostCSS даёт полную свободу. Вы можете использовать как готовые плагины (которых, к слову, уже довольно много), так и свои собственные. Написать плагин не составит труда, если вы программируете на JavaScript.

PostCSS имеет модульную архитектуру, а это значит что вам не потребуется устанавливать сразу все плагины за один раз — достаточно установить лишь сам PostCSS и нужные вам плагины. Ничего лишнего, в отличие от препроцессоров.

С PostCSS отпадает смысл использовать препроцессоры. Если вам требуется вложенность — подключите нужный плагин и сможете её использовать. Переменные, циклы, инклуды — всё это уже реализовано и доступно для использования прямо сейчас. Но всё это не так интересно, ведь это уже пройденный с препроцессорами этап. PostCSS предоставляет нам гораздо более интересные возможности. Например, чтобы не инлайнить картинки в CSS вручную, можно лишь указать путь к картинке, и плагин для PostCSS сам заинлайнит её. Но это всё мелочи. С помощью CSS-модулей PostCSS позволяет добиться полной изоляции стилей для каждого компонента на странице. Если без этого плагина вы не могли использовать два одинаковых класса на странице для стилизации разных компонентов, то с этим плагином можно благополучно забыть о проблеме конфликта имён классов. Хорошее применение такой плагин может найти и в вёрстке встраиваемых виджетов, подключаемых на разных сайтах. Это позволит избежать конфликтов стилей виджета со стилями сайта.

Короче говоря, на PostCSS можно самому написать свой препроцессор с блекджеком и куртизанками кучей новых фич. Возможности ограничены лишь вашей фантазией. Благодаря большому количеству плагинов можно даже не писать ничего своего, а сразу использовать готовое. На PostCSS можно делать всё — от модульных минификаторов до CSS на русском.

В заключение скажу, что нет смысла для каждой задачи, связанной со стилями, использовать отдельный инструмент. PostCSS с определённым набором плагинов способен справиться с огромным количеством задач, которые раньше мы решали с помощью препроцессоров, онлайн-сервисов, консольных утилит и вообще вручную.

2015   css   вёрстка   постцсс   препроцессоры