PostCSS. Будущее после Sass и Less
Андрей Ситник (Iskin, Злые марсиане)
В 2013 году Holowaychuk анонсировал свой проект Rework в статье «Модульный CSS-препроцессинг с Реворком» (http://tjholowaychuk.tumblr.com/post/44267035203/modular-css-preprocessing-with-rework).
Как раз тогда я искал какой-то инструмент для того, чтобы сделать автопрефиксер. Когда я прочитал эту статью, я был поражен, потому что это был действительно революционный подход, он менял все. И поэтому первые версии автопрефиксера базировались на Rework«е. Но, к сожалению, Rework — это был Proof Of Concept, это было первое поколение, чтобы доказать, что это вообще работает. Поэтому мы его жестко форкнули, переманили всех разработчиков, устроили маленькую революцию и сделали PostCSS.
PostCSS — это второе поколение модульного процессора.
Так что же такое PostCSS?
PostCSS — это модульный препроцессор, в ядре которого очень простое. Ядро состоит из двух вещей:
- Парсер, который на вход принимает CSS-строку и на выход выдает дерево объектов javascript«овских. AST (абстрактное синтаксическое дерево).
- Стригифайр, который он делает обратную вещь — он на вход получает то абстрактное дерево в виде объектов, и на выход выдает новый CSS. По умолчанию ядро PostCSS очень удобное, очень полезное, но оно не делает ничего. Оно парсит ваш CSS, а потом обратно превращает его в строку и превращает так, что сохраняется байт в байт, даже пробельные символы.
Вся магия находится в этих плагинах.
Что такое плагин? Плагин — это такая javascript функция, которая на вход принимает AST, проходится по каким-то его узлам, что-то ищет, что-то меняет, что-то добавляет и измененное дерево возвращает обратно. В измененное дерево идет следующий плагин… Получается цепочка. А в конце — магический стригифайр, который берет это измененное дерево, сохраняет его в новую строку, и генерирует карты кода, сорсмэпа. Генерирует новые, либо обновляет старые.
Как говорил Торвальдс, «покажите мне код», потому что мы все программисты, код — это важно.
Как это выглядит? PostCSS — это NP-библиотека, мы грузим ее из NP. Далее мы создаем инстанс, создаем объект процессора и передаем те плагины, которые были на прошлом шаге и все. Мы берем и через этот процессор прогоняем наш CSS. И получаем результат с помощью промиса.
Пример плагина:
В препроцессорах нельзя сделать полифил для единицы измерения. Давайте напишем его на PostCSS. Плагин — это функция, которая на вход принимает CSS, дерево объектов, которое будет в переменной CSS. Далее у этого дерева есть такие волшебные функции — чтоб вам было удобно программировать, есть итератор по всем свойствам, внутри, оно рекурсивно. И мы берем и проходимся по всем свойствам. Это, кстати, заметьте ES6. Мы итерируемся по всем свойствам, ищем в свойствах значение rem и заменяем его на пиксели. Закрываем скобочки, потому что у нас, к сожалению, не CoffeeScript. Это весь код, который вам нужно написать, чтобы сделать такой базовый полифил для rem«a.
В чем разница?
Всегда нужно знать, кого бить, а кого нет, т.е. у нас должны быть точные критерии, где препроцессор, где постпроцессор. Препроцессор — он монолитный, все функции встроены в ядро, все переменные, примеси — все это там внутри, весь синтаксис. А вторая вещь — у вас код прямо в шаблоне, у вас полноценный язык программирования.
В PostCSS все в виде плагинов, ядро не делает ничего. А второй момент — у вас код и стили отдельно, получается, что у вас код на нормальном языке программирования javascript, a CSS — отдельно в CSS.
Почему это так важно? Потому что эти плагины реализуют магическую вещь — эволюцию.
Вам приходит какая-то безумная идея, и ваши друзья над вами смеются. Вы берете и реализуете ее в виде плагина, например, какой-то новый метод оптимизации, и публикуете его. Над вами, к сожалению, продолжают смеяться, потому что haters gonna hate, но, как минимум, некоторые люди понимают это, начинают это использовать, проверять. У них получается, их больше берут на работу, а тех, кто над вами смеялся, увольняют. Через некоторое время получается, что большинство пользователей пользуются вашим плагином. Не потому что идея красивая, а потому что она реально работает на практике. И когда у нас есть популярность, мы можем прийти в W3C и либо написать им черновик, либо попросить кого-то другого сделать спецификацию. Потому что делать спецификацию, когда у нас нет какого-то реального практического применения, нет практики, никто не знает, работает это или нет, никто не будет. Но если у вас есть популярность, вы пишете спецификацию и идете на новый круг, новые унижения, новый плагин и т.п.
Это была теория. Современная наука говорит очень правильную вещь — теория не значит ничего без практики. Если идея действительно работает, у нас будет реальный практический результат, у нас будет что-то. Если PostCSS работает, значит он будет лучше препроцессора, значит у нас будет что-то живое, что-то, что можно потрогать. Давайте посмотрим, есть ли это.
Первое. Само собой, в PostCSS есть переменные, это не сложно, есть вложенность, тоже не сложно, с амперсандом, как все любят, потому что БЭМ, само собой есть примеси, синтаксис чуть-чуть другой, но такой же. Но в чем важный момент? Все это сделано в виде плагинов. И переменные, и вложенность, и примеси. Например, для переменных есть два плагина, один плагин реализует старый добрый Sass-стиль, а другой реализует синтаксис W3C, css custom properties.
Второй важный момент — это то, что он невероятно маленький. Например, вложенность — это 60 строк обычного javascript-кода. Вы можете взять и исправить это, а если я откажусь это принять, вы можете взять и форкнуть. Это совершенно не проблема, вы за день можете сделать другую вложенность.
PostCSS это не про то, чтобы делать работу Sass«а модульно, потому что это же не так круто. Модульность — не модульность, кого это волнует? Главный вопрос:, а можно ли сделать больше, можно ли сделать какую-то совершенно новую магию? И вот автопрефиксер — главный пример, т.е. вы просто пишете обычный CSS, а автопрефиксер сам. У него есть база данных Can I Use, он сам находит те свойства, которым нужны именно сейчас префиксы, добавляет их, при этом делая всякую сложную магию.
Более интересный пример cssnext.
В Javascript сейчас можно использовать тот Javascript, который еще не в браузерах, будущий. И у вас есть компилятор, который компилирует его в текущий. Было бы круто делать это все в CSS. Например, у нас есть CSS 4, там куча новых вкусных вещей. Например, можно объявить свой дополнительный селектор, кастомный, ваш личный и использовать его. И для этого у нас есть cssnext.
Cssnext — это транспайлер. Вы пишете CSS 4 прямо сейчас, а оно компилируется в CSS 3. Это к вопросу о том, что невозможно сделать на Sass. Кроме кастомных селекторов у вас, например, есть стандартизированная функция работа с цветом и, в том числе, всякие удобные сокращения. Прямо сейчас, можете прийти и добавить.
Но сейчас будет страшная история.
Китай, огромный рынок, много денег, все дела, но там творится — ужас! Там до сих пор популярен Е7, 8-ой и даже 6-ой. Это ужасно, а денег хочется. Поэтому китайская компания Alibaba написала плагин cssgrace. Это как cssnext, только наоборот. Он не из хорошего делает средний, а он, наоборот, из среднего делает плохой код. Она проходится по вашему CSS и находит те свойства, которые не будут работать в вашем Е, и заменяет их на хаки. Это немного похоже на примеси, но почему это круто, и почему это важно, что это невозможно на Sass? Потому что с примесями вам нужно помнить, где вам нужно написать примеси, вы должны помнить, что opacity не поддерживается. А тут вы просто пишете и не думаете об этом, а за вас думают китайцы, миллиард китайцев.
Кроме того, всякая магия со свойствами, и можно делать магию с селекторами. Есть жуткий хак, было бы круто сказать, что если у нас четыре элемента в родителе, то давай мы сделаем ширину 25%, а если пять, то 20. И это можно сделать прямо сейчас. Хак жуткий, вы вручную писать не будете, но с помощью этого плагина или PostCSS, он добавляет вам дополнительный селектор.
Или другая вещь. Выше все было про то, как писать код, а это про то, как делать код, чтоб ваш сайт грузился быстрее.
Есть спрайты, а есть бесидж 3 кодирование инлайн картинок, и у них есть свои плюсы и минусы. Вот было бы круто объединить их. При инлайне у вас разрастается ваша CSS, и получается, что когда пользователь заходит на сайт, пока он картинки не загрузит заинлайненные в CSS, он вообще ничего не увидит — это плохо. Было бы круто, если бы вначале загрузился дизайн, а потом картинки. И для этого есть волшебный плагин data-packer. Он проходится по вашему CSS, находит все картинки заинлайненные и выносит их в отдельный файл. Поэтому он обнаруживает, что два селектора используют одну и ту же картинку, и объединяет эти селекторы.
В итоге, когда пользователь заходит на сайт, он быстренько грузит маленький CSS дизайна, а потом долго CSS с картинками — удобно. Т.е. добавляете один плагин, и прямо сейчас ваш сайт становится быстрее.
Интересный момент. Кто поддерживает IЕ9? А кто поддерживает людей, у кого есть цветовая слепота? Проблема в том, что людей, которые не видят цвета, 5%, а пользователей IE старых — меньше. И это очень важно поддерживать. И нужно понимать, что это не черно-белое зрение. Все эти шутки про светофор — это не про цветовую слепоту. Например, так (слева) видит здоровый человек, а так (справа) видит человек с цветовой слепотой. Видите, что кнопка хуже заметна.
Это нужно тестировать, и с помощью PostCSS тестировать легко. Есть плагин. Вы во время разработки, например, делаете обычный билд и еще в один билд добавляете плагин. Этот плагин проходится по всем цветам вашего CSS и заменяет их на цвета, который видит человек с различными типами цветовой слепоты. Конечно же, есть более удобные инструменты, но мы же понимаем, что если вы не используете более удобные инструменты, значит, они вам не подходят. Но с помощью этого можете проверять сайт для людей с цветовой слепотой, используя эти простые инструменты.
Вот еще один интересный момент — PostCSS можно использовать не только, чтобы изменять ваш CSS, но и для того, чтобы его проверять. Например, Твиттер используют PostCSS для своего линтера, своего БЭМ-а. Это не очень клевый линтер, потому что простой, как все линтеры, которые вы уже, может быть, используете. А вот есть крутой линтер — doiuse:
Он работает как два префиксера, только он вас «линейкой бьет по пальцам». Он хранит в себе базу данных Can I Use, пробегается по вашему CSS и находит, что например: «Чувак, ты мне сказал, что ты IЕ хочешь поддерживать, а user selected не поддерживается IE, ты точно уверен, что ты его должен был написать?». Это очень удобная вещь.
Это мой самый любимый плагин. Так выглядит Википедия на иврите. Почему? Потому что евреи и арабы пишут в другую сторону. Это очень старое письмо. А дело в том, что (вы никогда не задумывались, почему будущее вон там — справа?) Будущее справа, потому что мы пишем слева направо. А если мы пишем в другую сторону, то будущее в нашей голове будет слева. И поэтому прогресс бар для евреев и арабов должен идти в другую сторону. И это касается не только прогресс бара, а вообще письменность влияет на восприятие пространства.
И что будет, если ИГИЛ возьмет вас в рабство и заставит верстать им сайты? Вы же не будете поддерживать две версии стилей. Одну для западной аудитории, а другую — для арабской. И поэтому парень из Иордана (он, вроде бы, не в ИГИЛ-е, слава богу) написал плагин, через который вы прогоняете CSS, и он заменяет left на right, right на left… И такую штуку он генерирует сам. Т.е. на вход обычная Википедия, а на выходе Википедия отзеркаленная. Это мой самый любимый плагин, который показывает, что невозможно на Sass.
Сейчас я рассказал только про те плагины, которые сейчас совсем невозможны на Sass«e, чтобы вас шокировать. На самом деле, у нас очень много разных плагинов, которые иногда более полезны, просто они не настолько круто выглядят. Вы можете зайти на наш github и посмотреть все плагины, там много интересного, много всякого синтетического сахара, оптимизации, расширения языка, поддержки старых браузеров и поддержки будущих браузеров.
Есть очень сложный вопрос. Я показал вещи, которые может делать PostCSS, которые невозможны на Sass. PostCSS может делать гораздо больше. Это невероятный, более мощный инструмент, но возникает вопрос:, а может ли более мощный инструмент быть быстрее? Потому что в libsass сделали невероятную вещь с помощью оптимизации на Си, они очень быстры. Можно ли переплюнуть результат libsass? И ответ — да.
Это главный пример, почему модульная архитектура — это так круто, так важно. Потому что модульную архитектуру очень легко оптимизировать. У нас куча маленьких модулей. Мы можем понять, что у нас тормозит этот модуль, взять и оптимизировать его. И поэтому PostCSS написан на Javascript — в 4 раза быстрее libsass, написанный на С++. Это к вопросу о том, когда бэкендер будет говорить вам о том, что «давайте теперь пишем все на Си, это быстрее», то нет, это не быстрее.
Еще раз: какие преимущества PostCSS, почему оно лучше, чем Sass?
- PostCSS гораздо быстрее. Т.е. даже если вы довольны скоростью libsass, используя PostCSS, вы можете сделать больше вещей, вы можете делать какую-то более сложную оптимизацию. Это огромное пространство.
- Вторая вещь — это модульность, вы можете взять и форкнуть проект, вы можете использовать разные идеи.
- А третья вещь — самая важная, что PostCSS больше чем Sass. Вы можете на PostCSS делать любую фичу, которая есть в Sass, но на Sass вы не можете сделать большинство фич, которые есть в PostCSS.
Но я обманул вас. В названии доклада говорилось, что PostCSS — это будущее после Sass. На самом деле, это настоящее. У нас уже прямо сейчас больше полумиллиона загрузок в месяц с Can I Use. Огромная аудитория. Поэтому, если вы боитесь по поводу продакшн-реди, не бойтесь, мы действительно проверяем PostCSS на огромной аудитории. PostCSS пользуются очень большие компании.
Paul Irish говорил, что автопрефиксер с PostCSS используется в Google. Taobao — это крупнейший Интернет-магазин Китая, он не просто использует PostCSS, разные плагины, он их и пишет. Wordpress использует два плагина. Автопрефиксер rtl css — для арабской версии. И Твиттер не просто использует PostCSS, они в какой-то момент взяли и выкинули Less. У них используют только постпроцессоры. Только этот способ подхода.
Кроме того, PostCSS становится трендом. Например, A List Apart написала интересную статью о постпроцессорах, о том, как постпроцессоры PostCSS спасет нас от темной стороны CSS-процессоров (http://alistapart.com/column/what-will-save-us-from-the-dark-side-of-pre-processors).
Или например, перебежчик в наш лагерь, Бен Фрейн автор книги «Sass и Compass для дизайнеров» написал статью о том, как он расставался с Sass и переходил на PostCSS (http://benfrain.com/breaking-up-with-sass-postcss).
Но самый клевый твит, это конечное же, Bootsstrap. Они написали, что они настолько вдохновлены CSSnext«ом, им это так понравилось, что Bootstrap 5 скорее всего будет на PostCSS (https://twitter.com/mdo/status/591364406816079873). Сейчас он на Less, потом он будет на Sass, а Sass они собираются выкидывать и переходить на PostCSS.
Т.е. что я хочу, чтобы вы сделали, когда пришли на этих выходных домой?
Первый момент: если вы делаете какой-то интересный инструмент для обработки CSS, подумайте о том, чтобы использовать PostCSS. PostCSS гораздо лучше, чем Regexp, потому что Regexp опасный — они изменяют вам карты кода и т.п. вещи.
Второй момент — препроцессоры. Вот, например, еще один перебежчик в наш лагерь — разработчик Grid«а, примеси для реализации сетки lost, который писал Макеев в очень интересном твиттере веб-стандартов, — он перешел на постпроцессоры, ему так понравилось, почему? Потому что раньше было нужно поддерживать три версии — одну для Stylus«а, одну для Less, другую для Sass. Это было очень нудно. А тут он понял: зачем это делать? Он просто возьмет как автопрефиксер. Он взял PostCSS, и его могут использовать пользователи Sass, пользователи Less и т.д.
Если вы делаете сайты, делаете инструмент и не используете PostCSS, добавьте автопрефиксер прямо сейчас. Это очень важно, почему? Потому что Google рекомендует единственный инструмент для работы с префиксами. Это только PostCSS, все остальные элементы гораздо хуже, есть много причин почему.
Третий момент. Если вы уже используете PostCSS, например, для автопрефиксера, посмотрите на другие плагины. Я советую начать с cssnext, потому что он реально клевый, это возможность писать на CSS 4 сейчас. Кроме этого, посмотрите список плагинов, мне кажется, что это понравится.
И четвертый момент. Если вы начинаете новый проект, я не рекомендую выкидывать Sass прямо сейчас, потому что PostCSS может работать хорошо и после Sass. Зачем его выкидывать? Если вы начинаете новый проект, подумайте, а зачем вам делать переменные, вложенности, примеси на препроцессорах. PostCSS тоже это имеет, если вы используете автопрофиксер, зачем вам парсить файл дважды? Просто добавьте переменные, вложенности, примеси в PostCSS перед вашим автопрефиксером.
Потому что IT же не про программирование, IT не про код. Потому что, по-хорошему, аську можно было сделать в телеграмме. Почему IT появилось сейчас? Потому что мы сейчас находимся в том времени, когда мы не можем решить задачи, стоящие перед нами. Все задачи, которые мы решаем сложнее, чем помещается в наш ум. В этом идея IT. IT — это борьба со сложностью. А что проще — два инструмента или один? По мне, так один.
Контакты
» Iskin
» Вконтакте
» Evil martians
Этот доклад — расшифровка одного из лучших выступлений на конференции фронтенд-разработчиков FrontendConf. Мы уже открыли подготовку к 2017 году, а подписавшись на список рассылки конференции Вы получите 8 лучших докладов прошлого года.Самая сложная секция грядущей конференции HighLoad++ это »Производительность фронтенда». Фронтенд стал большим, это уже полноценный софт со своей архитектурой, моделями и данными (а не просто интерфейс, как было раньше). Именно в этом разрезе мы и изучаем его на этой секции.
Вот некоторые из планируемых докладов:
- Промышленное ускорение сайтов / Николай Мациевский (Айри.рф);
- Your hero images need you: Save the day with HTTP2 image loading / Tobias Baldauf (Akamai Technologies);
- The Accelerated Mobile Pages (AMP) Project: What lies ahead? / Paul Bakaus (Google);
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB);
Instant Loading: Building offline-first Progressive Web Apps / Alex Russell (Google);
Комментарии (5)
22 сентября 2016 в 16:44
+3↑
↓
Что то наверное я слишком старым стал, не понимаю зачем все это нужно.22 сентября 2016 в 17:19
0↑
↓
Ответ прост, все ради простоты =)
22 сентября 2016 в 17:11
0↑
↓
Скорее бы CSS4 приняли и браузеры поддержали, тогда бы все эти пре-процессоры и пост-процессоры не нужны были бы в большинстве случаев.22 сентября 2016 в 17:19
0↑
↓
Картинка про разницу — «в огороде бузина, в Киеве дядька».
Он хранит в себе базу данных Can I Use, пробегается по вашему CSS и находит, что например: «Чувак, ты мне сказал, что ты IЕ хочешь поддерживать, а user selected не поддерживается IE, ты точно уверен, что ты его должен был написать?». Это очень удобная вещь.
Какой в этом смысл? 99% что я специально написал это правило и специально пренебрег его поддержкой в IE — graceful degradation.
rtlcss
Почему это невозможно на sass и зачем там вообще sass, если вопрос решается так:
[dir="rtl"] a { right: 10px; text-align: right; }
22 сентября 2016 в 18:27
0↑
↓
Ну вот, а я сам писал парсер CSS в AST для домашнего минимизатора имен классов. Быть может, перееду на PostCSS.