Из Sass в PostCSS

Из Sass в PostCSS

От автора: я работал с Sass на протяжении многих лет. Но сейчас я хочу поменять способ написания стилей с помощью PostCSS и плагина cssnext. Мне нравится идея, что уже сегодня можно писать CSS синтаксисом будущего и использовать инструменты, подходящие под те, к которым я привык. Мой личный сайт идеально подходит для тестирования новых функций.

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

Частичный импорт

переменные

вложенность

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее

миксины

extend

классы плейсхолдеры

функции цвета darken и rgba

сжатие

Подготовка

Перед переходом на новый синтаксис мне нужно было проделать много бесполезной работы. Файловая структура проекта была заточена под Sass. Для частей я использовал нижнее подчеркивание в названиях, а также подключил расширение scss. У меня было две папки под Sass файлы. В папке modules хранился Sass, не конвертирующийся в CSS. Это переменные, классы плейсхолдеры и миксины. В папке partials хранились все файлы Sass, конвертирующиеся в CSS.

Начальная файловая структура:

css/
  scss/
 modules/
 _module.scss
 ...
 partials/
 _partial.scss
 ...
 tylergaw.scss

Все части Sass импортировались в файл tylergaw.scss.

@import "modules/setup";
@import "modules/reset";
@import "modules/fonts";

Я перестроил структуру и переименовал файлы. Первым делом я сменил расширение с scss на css. Я использовал скрипт Bash:

for f in *.scss; do git mv -- "$f" "${f%.scss}.css"; done;

Подчеркивания тоже были взяты из Sass, их я тоже удалил. Я не додумался, как сделать это через Bash, поэтому пришлось удалять их вручную. (заметка себе: улучшить знания по Bash)

Последний этап был – переместить все CSS файлы в папку modules и удалить папку partials. Я решил, что обращаться ко всем CSS файлам в виде модулей намного лучше, чем делить их по папкам modules/partials.

Установка билда

Я начал с PostCSS CLI. Добавил временный скрипт в файл package.json:

"scripts": {
  "postcss": "postcss -o public/css/tylergaw.css src/css/tylergaw.css"
}

Скомпилировал CSS, не меняя стили:

npm run postcss

И получилось! Почти. Ошибок в консоли не было, но в один прекрасный день я получил голую страницу.

Из Sass в PostCSS

Результат первого билда PostCSS

Теперь с помощью функционала я мог вернуть стили на место.

Заглянув в консоль в Chrome, я увидел несколько ошибок 404. Так я обнаружил первую отсутствующую функцию — @import. В файле tylergaw.css были только @import’ы для всех CSS модулей. Браузер видел код и делал, что умеет. Он пытался загрузить каждый модуль через HTTP запрос. Мой билд копирует только один CSS файл, а не все модули. Поэтому браузер и не смог их найти.

Я мог изменить процесс и заставить работать @import’ы, но это было бы неэффективно. Нужна была замена @import из Sass.

Первый плагин

Для замены @import из Sass я использовал плагин postcss-import. После установки модуля через npm я обновил скрипт:

"scripts": {
  "postcss": "postcss -u postcss-import -o public/css/tylergaw.css src/css/tylergaw.css"
}

Запустил скрипт еще раз с помощью npm run postcss. В одном CSS файле хранились все модули, и на сайт частично вернулись стили.

Из Sass в PostCSS

Результаты билда PostCSS с плагином postcss-import

Появится ли импорт в CSS?

Встраивание через @import перевернуло всю игру в Sass. После появления этой функции мы смогли лучше организовывать стили. Не уверен, что этот функционал когда-нибудь появится в обычном CSS. Похоже, для таких вещей всегда будут нужны билды, что не так уж и плохо.

Плагин postcss-import станет обязательным для всех моих будущих проектов на PostCSS. Думаю, у многих будет так же. Цитата разработчика плагина: «Этот плагин должен быть первым в вашем списке. Тогда другие плагины будут работать в AST, будто у вас всего один файл. Все будет работать так, как вы ожидаете.»

Плагин cssnext

cssnext – PostCSS плагин для компиляции будущего синтаксиса CSS в синтаксис, который работает уже сегодня. Важно отметить, что это не другой язык, как Sass или Less. Для всех предлагаемых функций еще только разрабатывается спецификация. Какие-то функции уже сейчас работают в браузерах. Другие только находятся на начальном этапе спецификации.

С помощью cssnext я заполнил оставшиеся проблемы, которые появились после ухода от Sass.

Вендорные префиксы

Когда я писал свой сайт, я еще не знал про Autoprefixer. Для добавления префиксов я использовал пользовательские Sass миксины. В cssnext встроен Autoprefixer, поэтому модуль с миксинами можно было удалить.

Переменные

Потом я заменил Sass переменные на пользовательские свойства CSS. В файле _setup.scss был код:

$grey: #1e1e1d;
$yellow: #ffad15;
$offwhite: #f8f8f8;
$darkerwhite: darken($offwhite, 15);

Это не все переменные Sass, но самые главные. Остальные находятся в отдельных модулях.

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее

Обратите внимание на разницу между пользовательскими свойствами и переменными. Пользовательские свойства действительны только для значений свойств. Их нельзя использовать в селекторах, названиях свойств и медиа запросах.

Обновленный файл setup.css:

:root {
  --white: #fff;
  --grey: #1e1e1d;
  --yellow: #ffad15;
  --offwhite: #f8f8f8;
  ...
}

Пример с новым использованием:

a {
  color: var(--yellow);
}

CSS пользовательские свойства отличаются от Sass переменных только синтаксисом. Из-за плохой поддержки в браузерах свойства до сих пор компилируются. В примере выше скомпилированное значение будет color: #ffad15.

Функции цвета

В предыдущем примере я оставил одну переменную $darkerwhite: darken($offwhite, 15);, ее тоже нужно заменить. Есть черновая спецификация для функции color. В плагине cssnext эта функция уже есть, и она очень крутая. Ниже показан код setup.css с пользовательским свойством darkerwhite и значением в виде функции color и shade:

:root {
  ...
  --offwhite: #f8f8f8;
  --darkerwhite: color(var(--offwhite) shade(20%));
  ...
}

У функции color множество модификаторов. За раз можно использовать несколько модификаторов:

background-color: color(#d32c3f shade(40%) alpha(40%));

Компилируется в:

background-color: rgba(127, 26, 38, 0.4);

Повторим. На данный момент cssnext компилирует color() в hex или rgba значение. Как только функция color будет поддерживаться в браузерах, компиляция станет не нужна, а цветом можно будет манипулировать на лету.

Вложенность

Вложенность – краеугольный камень CSS препроцессоров. Вложенность необходима для комфортной стилизации. Tab Atkins разрабатывает спецификацию вложенности для CSS, а плагин cssnext позволяет использовать эту функцию уже сейчас.

Это были цветочки. В синтаксисе вложенности используется знак & перед вложенными блоками. Например, ниже представлен код Sass со страницы моего проекта:

.projects-list {
  ...

  li {
 & > div {...}
  }

  a {
 ...

 &:hover,
 &:focus {...}

 &::after {...}
  }

  @media (min-width: 640px) {...}
}

Я добавил вложенность, код превратился в:

.projects-list {
  ...

  & li {
 & > div {...}
  }

  & a {
 ...

 &:hover,
 &:focus {...}

 &::after {...}
  }

  @media (min-width: 640px) {...}
}

Для базовой вложенности необходимо использовать символ &. Псевдоклассы и селекторы в Sass и CSS одни и те же. В медиа запросах символ & не нужен.

Также нужно упомянуть @nest. Как сказано в документации, сложная вложенность требует @nest вместо &. В этом проекте он мне не пригодился, может, в следующих понадобится.

Extend и классы плейсхолдеры

Для общих стилей в Sass я использовал @extend и классы плейсхолдеры. Пример использования для заголовков:

%futura {
  font-family: 'futura-pt', helvetica, sans-serif;
}

%futura-heading {
  @extend %futura;
  font-weight: 700;
  line-height: 1.1;
  text-transform: uppercase;
}

и пример использования:

.my-heading {
  @extend %futura-heading;
}

Как использовать пользовательские свойства мы уже посмотрели. Для правила @apply есть спецификация, находящаяся в разработке. Это правило позволяет хранить набор свойств и ссылаться на них в селекторах. Я использовал @apply вместо extend.

Вернемся в setup.css, я обновил свойства заголовка:

:root {
  ...

  --franklin: {
 font-family: 'futura-pt', helvetica, sans-serif;
  };

  --franklin-heading: {
 @apply --franklin;
 font-weight: 700;
 line-height: 1.1;
 text-transform: uppercase;
  };
}

и пример использования:

.my-heading {
  @apply --franklin-heading;
}

Правило @apply не эквивалент extend. В текущей форме в плагине cssnext правило @apply копирует свойства и значения для каждого правила. Наш проект маленький, поэтому нам это не важно. В больших проектах лишние свойства будут засорять код. Лучше, наверное, использовать общие названия классов для получения таких же результатов.

На данном этапе мой сайт выглядел ровно так же, как до изменений. Исключением была страница проектов. Там я использовал разные цвета для каждой плитки проекта. Ниже я объясню, как правильно стилизовать эту страницу без Sass и лишнего кода.

Из Sass в PostCSS

Цветные плитки страницы проектов

Миксины с аргументами

Чтобы упростить написание стилей, я использовал Sass миксины. Миксин принимал один аргумент, цвет плитки. Миксин project-block:

@mixin project-block ($c) {
  background-color: $c;

  a {
 color: $c;

 &:hover {
 background-color: $c;
 color: $offwhite);
 }
  }
}

и пример использования:

.p-jribbble {
  @include project-block(#ff0066);
}

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

Но это не означает, что моя удача закончилась. Мой CSS длиннее Sass, но не намного. Также я использовал еще одну CSS функцию, которая находится в разработке, совпадающие селекторы.

Пример CSS замены миксина project-block:

.p-jribbble,
.p-jribbble a:matches(:hover, :focus) {
  background-color: var(--color-jrb);

  & a {
 color: var(--color-jrb);
  }
}

Переменные цвета заданы в :root выше в файле. Плагин cssnext компилирует CSS выше в:

.p-jribbble,
.p-jribbble a:hover,
.p-jribbble a:focus {
  background-color: #ff0066
}

.p-jribbble a,
.p-jribbble a:hover a,
.p-jribbble a:focus a {
  color: #ff0066;
}

Последние два селектора …a a:hover и …a a:focus не совпадают ни с одним элементом. Они необязательны, но кроме пары байт они никак не влияют на код. Для лучшей читаемости я вкладывал селектор a.

Еще больше PostCSS

Вернув стили в порядок, я решил добавить еще несколько PostCSS плагинов. Для объединения медиа запросов с одним условием я использовал css mqpacker. Для оптимизации кода я взял плагин cssnano.

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

Заключение

Поработав с этими настройками пару дней, я совсем вымотался. Переключиться с Sass на новый синтаксис CSS было легко. И это после 5-6 лет использования Sass во всех своих проектах.

Мне нравится, как изменилось мое мышление. У плагина cssnext есть похожий подход для CSS, как у Babel для JS. Оба подхода позволяют писать на нормальном языке, а также на его будущей версии.

Автор: Tyler Gaw

Источник: https://tylergaw.com/

Редакция: Команда webformyself.

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами Less и Sass с полного нуля менее чем за 2 недели

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Препроцессоры. Быстрый старт

Овладейте азами работы с препроцессорами с полного нуля

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree