Андрей Ситник (Iskin, Злые марсиане)
![Андрей Ситник](https://habrastorage.org/getpro/habr/post_images/70d/eb5/ac1/70deb5ac138474adfdcc077533df1391.jpg)
В 2013 году Holowaychuk анонсировал свой проект Rework в статье «Модульный CSS-препроцессинг с Реворком» (http://tjholowaychuk.tumblr.com/post/44267035203/modular-css-preprocessing-with-rework ).
Как раз тогда я искал какой-то инструмент для того, чтобы сделать автопрефиксер. Когда я прочитал эту статью, я был поражен, потому что это был действительно революционный подход, он менял все. И поэтому первые версии автопрефиксера базировались на Rework’е. Но, к сожалению, Rework – это был Proof Of Concept, это было первое поколение, чтобы доказать, что это вообще работает. Поэтому мы его жестко форкнули, переманили всех разработчиков, устроили маленькую революцию и сделали PostCSS.
PostCSS – это второе поколение модульного процессора.
Так что же такое PostCSS?
![](https://habrastorage.org/getpro/habr/post_images/7e4/30a/672/7e430a672f5ba36a6a38719041f95d0f.png)
PostCSS – это модульный препроцессор, в ядре которого очень простое. Ядро состоит из двух вещей:
- Парсер, который на вход принимает CSS-строку и на выход выдает дерево объектов javascript’овских. AST (абстрактное синтаксическое дерево).
- Стригифайр, который он делает обратную вещь – он на вход получает то абстрактное дерево в виде объектов, и на выход выдает новый CSS. По умолчанию ядро PostCSS очень удобное, очень полезное, но оно не делает ничего. Оно парсит ваш CSS, а потом обратно превращает его в строку и превращает так, что сохраняется байт в байт, даже пробельные символы.
Вся магия находится в этих плагинах.
Что такое плагин? Плагин – это такая javascript функция, которая на вход принимает AST, проходится по каким-то его узлам, что-то ищет, что-то меняет, что-то добавляет и измененное дерево возвращает обратно. В измененное дерево идет следующий плагин… Получается цепочка. А в конце – магический стригифайр, который берет это измененное дерево, сохраняет его в новую строку, и генерирует карты кода, сорсмэпа. Генерирует новые, либо обновляет старые.
Как говорил Торвальдс, «покажите мне код», потому что мы все программисты, код – это важно.
![](https://habrastorage.org/getpro/habr/post_images/9b2/bed/1fc/9b2bed1fc8c6e3a8dfe7a828919bf235.png)
Как это выглядит? PostCSS – это NP-библиотека, мы грузим ее из NP. Далее мы создаем инстанс, создаем объект процессора и передаем те плагины, которые были на прошлом шаге и все. Мы берем и через этот процессор прогоняем наш CSS. И получаем результат с помощью промиса.
Пример плагина:
![](https://habrastorage.org/getpro/habr/post_images/0ef/bb7/3ec/0efbb73ec0c9a1393f1411071c443911.png)
В препроцессорах нельзя сделать полифил для единицы измерения. Давайте напишем его на PostCSS. Плагин – это функция, которая на вход принимает CSS, дерево объектов, которое будет в переменной CSS. Далее у этого дерева есть такие волшебные функции – чтоб вам было удобно программировать, есть итератор по всем свойствам, внутри, оно рекурсивно. И мы берем и проходимся по всем свойствам. Это, кстати, заметьте ES6. Мы итерируемся по всем свойствам, ищем в свойствах значение rem и заменяем его на пиксели. Закрываем скобочки, потому что у нас, к сожалению, не CoffeeScript. Это весь код, который вам нужно написать, чтобы сделать такой базовый полифил для rem’a.
В чем разница?
![](https://habrastorage.org/getpro/habr/post_images/bf5/e5a/b56/bf5e5ab56dbadafabaeaf6e44d6388dc.png)
Всегда нужно знать, кого бить, а кого нет, т.е. у нас должны быть точные критерии, где препроцессор, где постпроцессор. Препроцессор – он монолитный, все функции встроены в ядро, все переменные, примеси – все это там внутри, весь синтаксис. А вторая вещь – у вас код прямо в шаблоне, у вас полноценный язык программирования.
В PostCSS все в виде плагинов, ядро не делает ничего. А второй момент – у вас код и стили отдельно, получается, что у вас код на нормальном языке программирования javascript, a CSS – отдельно в CSS.
Почему это так важно? Потому что эти плагины реализуют магическую вещь – эволюцию.
![](https://habrastorage.org/getpro/habr/post_images/aa7/f91/1cd/aa7f911cdc35aee764739c166755de54.png)
Вам приходит какая-то безумная идея, и ваши друзья над вами смеются. Вы берете и реализуете ее в виде плагина, например, какой-то новый метод оптимизации, и публикуете его. Над вами, к сожалению, продолжают смеяться, потому что haters gonna hate, но, как минимум, некоторые люди понимают это, начинают это использовать, проверять. У них получается, их больше берут на работу, а тех, кто над вами смеялся, увольняют. Через некоторое время получается, что большинство пользователей пользуются вашим плагином. Не потому что идея красивая, а потому что она реально работает на практике. И когда у нас есть популярность, мы можем прийти в W3C и либо написать им черновик, либо попросить кого-то другого сделать спецификацию. Потому что делать спецификацию, когда у нас нет какого-то реального практического применения, нет практики, никто не знает, работает это или нет, никто не будет. Но если у вас есть популярность, вы пишете спецификацию и идете на новый круг, новые унижения, новый плагин и т.п.
Это была теория. Современная наука говорит очень правильную вещь – теория не значит ничего без практики. Если идея действительно работает, у нас будет реальный практический результат, у нас будет что-то. Если PostCSS работает, значит он будет лучше препроцессора, значит у нас будет что-то живое, что-то, что можно потрогать. Давайте посмотрим, есть ли это.
![](https://habrastorage.org/getpro/habr/post_images/38a/017/ef2/38a017ef29833bf7fa020bb4aee37676.png)
Первое. Само собой, в PostCSS есть переменные, это не сложно, есть вложенность, тоже не сложно, с амперсандом, как все любят, потому что БЭМ, само собой есть примеси, синтаксис чуть-чуть другой, но такой же. Но в чем важный момент? Все это сделано в виде плагинов. И переменные, и вложенность, и примеси. Например, для переменных есть два плагина, один плагин реализует старый добрый Sass-стиль, а другой реализует синтаксис W3C, css custom properties.
![](https://habrastorage.org/getpro/habr/post_images/a27/a55/7b7/a27a557b73732622702371a5828e1d11.png)
Второй важный момент – это то, что он невероятно маленький. Например, вложенность – это 60 строк обычного javascript-кода. Вы можете взять и исправить это, а если я откажусь это принять, вы можете взять и форкнуть. Это совершенно не проблема, вы за день можете сделать другую вложенность.
![](https://habrastorage.org/getpro/habr/post_images/0d3/819/9b3/0d38199b3e8f05479848b21acfa0b4ad.png)
PostCSS это не про то, чтобы делать работу Sass’а модульно, потому что это же не так круто. Модульность – не модульность, кого это волнует? Главный вопрос: а можно ли сделать больше, можно ли сделать какую-то совершенно новую магию? И вот автопрефиксер – главный пример, т.е. вы просто пишете обычный CSS, а автопрефиксер сам. У него есть база данных Can I Use, он сам находит те свойства, которым нужны именно сейчас префиксы, добавляет их, при этом делая всякую сложную магию.
![](https://habrastorage.org/getpro/habr/post_images/40f/9d5/8f4/40f9d58f40a6e532a12b6540e08b16a3.png)
Более интересный пример cssnext.
В Javascript сейчас можно использовать тот Javascript, который еще не в браузерах, будущий. И у вас есть компилятор, который компилирует его в текущий. Было бы круто делать это все в CSS. Например, у нас есть CSS 4, там куча новых вкусных вещей. Например, можно объявить свой дополнительный селектор, кастомный, ваш личный и использовать его. И для этого у нас есть cssnext.
Cssnext – это транспайлер. Вы пишете CSS 4 прямо сейчас, а оно компилируется в CSS 3. Это к вопросу о том, что невозможно сделать на Sass. Кроме кастомных селекторов у вас, например, есть стандартизированная функция работа с цветом и, в том числе, всякие удобные сокращения. Прямо сейчас, можете прийти и добавить.
Но сейчас будет страшная история.
![](https://habrastorage.org/getpro/habr/post_images/17d/74e/724/17d74e724b628f9c4c44987797ee3dae.png)
Китай, огромный рынок, много денег, все дела, но там творится – ужас! Там до сих пор популярен Е7, 8-ой и даже 6-ой. Это ужасно, а денег хочется. Поэтому китайская компания Alibaba написала плагин cssgrace. Это как cssnext, только наоборот. Он не из хорошего делает средний, а он, наоборот, из среднего делает плохой код. Она проходится по вашему CSS и находит те свойства, которые не будут работать в вашем Е, и заменяет их на хаки. Это немного похоже на примеси, но почему это круто, и почему это важно, что это невозможно на Sass? Потому что с примесями вам нужно помнить, где вам нужно написать примеси, вы должны помнить, что opacity не поддерживается. А тут вы просто пишете и не думаете об этом, а за вас думают китайцы, миллиард китайцев.
![](https://habrastorage.org/getpro/habr/post_images/070/101/e3f/070101e3fdcdc479b5e17b83915e6324.png)
Кроме того, всякая магия со свойствами, и можно делать магию с селекторами. Есть жуткий хак, было бы круто сказать, что если у нас четыре элемента в родителе, то давай мы сделаем ширину 25%, а если пять, то 20. И это можно сделать прямо сейчас. Хак жуткий, вы вручную писать не будете, но с помощью этого плагина или PostCSS, он добавляет вам дополнительный селектор.
![](https://habrastorage.org/getpro/habr/post_images/fae/1cb/1ef/fae1cb1ef3ce5860d85d78e771e98876.png)
Или другая вещь. Выше все было про то, как писать код, а это про то, как делать код, чтоб ваш сайт грузился быстрее.
Есть спрайты, а есть бесидж 3 кодирование инлайн картинок, и у них есть свои плюсы и минусы. Вот было бы круто объединить их. При инлайне у вас разрастается ваша CSS, и получается, что когда пользователь заходит на сайт, пока он картинки не загрузит заинлайненные в CSS, он вообще ничего не увидит – это плохо. Было бы круто, если бы вначале загрузился дизайн, а потом картинки. И для этого есть волшебный плагин data-packer. Он проходится по вашему CSS, находит все картинки заинлайненные и выносит их в отдельный файл. Поэтому он обнаруживает, что два селектора используют одну и ту же картинку, и объединяет эти селекторы.
В итоге, когда пользователь заходит на сайт, он быстренько грузит маленький CSS дизайна, а потом долго CSS с картинками – удобно. Т.е. добавляете один плагин, и прямо сейчас ваш сайт становится быстрее.
![](https://habrastorage.org/getpro/habr/post_images/5be/945/12c/5be94512c690c7144e5e72d065d9d75e.png)
Интересный момент. Кто поддерживает IЕ9? А кто поддерживает людей, у кого есть цветовая слепота? Проблема в том, что людей, которые не видят цвета, 5%, а пользователей IE старых – меньше. И это очень важно поддерживать. И нужно понимать, что это не черно-белое зрение. Все эти шутки про светофор – это не про цветовую слепоту. Например, так (слева) видит здоровый человек, а так (справа) видит человек с цветовой слепотой. Видите, что кнопка хуже заметна.
Это нужно тестировать, и с помощью PostCSS тестировать легко. Есть плагин. Вы во время разработки, например, делаете обычный билд и еще в один билд добавляете плагин. Этот плагин проходится по всем цветам вашего CSS и заменяет их на цвета, который видит человек с различными типами цветовой слепоты. Конечно же, есть более удобные инструменты, но мы же понимаем, что если вы не используете более удобные инструменты, значит, они вам не подходят. Но с помощью этого можете проверять сайт для людей с цветовой слепотой, используя эти простые инструменты.
![](https://habrastorage.org/getpro/habr/post_images/9bf/0c5/6a7/9bf0c56a78397ac1c3e13d61d2968e2e.png)
Вот еще один интересный момент – PostCSS можно использовать не только, чтобы изменять ваш CSS, но и для того, чтобы его проверять. Например, Твиттер используют PostCSS для своего линтера, своего БЭМ-а. Это не очень клевый линтер, потому что простой, как все линтеры, которые вы уже, может быть, используете. А вот есть крутой линтер – doiuse:
![](https://habrastorage.org/getpro/habr/post_images/6bc/5c8/f46/6bc5c8f4612c1d3976f602f44c65e16a.png)
Он работает как два префиксера, только он вас «линейкой бьет по пальцам». Он хранит в себе базу данных Can I Use, пробегается по вашему CSS и находит, что например: «Чувак, ты мне сказал, что ты IЕ хочешь поддерживать, а user selected не поддерживается IE, ты точно уверен, что ты его должен был написать?». Это очень удобная вещь.
![](https://habrastorage.org/getpro/habr/post_images/194/f2f/621/194f2f6219f7625ca0f5475e5ea036e4.png)
Это мой самый любимый плагин. Так выглядит Википедия на иврите. Почему? Потому что евреи и арабы пишут в другую сторону. Это очень старое письмо. А дело в том, что (вы никогда не задумывались, почему будущее вон там – справа?) Будущее справа, потому что мы пишем слева направо. А если мы пишем в другую сторону, то будущее в нашей голове будет слева. И поэтому прогресс бар для евреев и арабов должен идти в другую сторону. И это касается не только прогресс бара, а вообще письменность влияет на восприятие пространства.
![](https://habrastorage.org/getpro/habr/post_images/7fe/5fc/4ad/7fe5fc4ad11af70376714650fdfdb2a2.png)
И что будет, если ИГИЛ возьмет вас в рабство и заставит верстать им сайты? Вы же не будете поддерживать две версии стилей. Одну для западной аудитории, а другую – для арабской. И поэтому парень из Иордана (он, вроде бы, не в ИГИЛ-е, слава богу) написал плагин, через который вы прогоняете CSS, и он заменяет left на right, right на left… И такую штуку он генерирует сам. Т.е. на вход обычная Википедия, а на выходе Википедия отзеркаленная. Это мой самый любимый плагин, который показывает, что невозможно на Sass.
![](https://habrastorage.org/getpro/habr/post_images/b8c/a06/d0c/b8ca06d0c4f24526bca8bd07041a11c0.png)
Сейчас я рассказал только про те плагины, которые сейчас совсем невозможны на Sass’e, чтобы вас шокировать. На самом деле, у нас очень много разных плагинов, которые иногда более полезны, просто они не настолько круто выглядят. Вы можете зайти на наш github и посмотреть все плагины, там много интересного, много всякого синтетического сахара, оптимизации, расширения языка, поддержки старых браузеров и поддержки будущих браузеров.
![](https://habrastorage.org/getpro/habr/post_images/1df/ac4/dbb/1dfac4dbb37378ee3b797625ca5d8034.png)
Есть очень сложный вопрос. Я показал вещи, которые может делать PostCSS, которые невозможны на Sass. PostCSS может делать гораздо больше. Это невероятный, более мощный инструмент, но возникает вопрос: а может ли более мощный инструмент быть быстрее? Потому что в libsass сделали невероятную вещь с помощью оптимизации на Си, они очень быстры. Можно ли переплюнуть результат libsass? И ответ – да.
![](https://habrastorage.org/getpro/habr/post_images/874/1bd/5e6/8741bd5e67d9193138dbd707d2f24931.png)
Это главный пример, почему модульная архитектура – это так круто, так важно. Потому что модульную архитектуру очень легко оптимизировать. У нас куча маленьких модулей. Мы можем понять, что у нас тормозит этот модуль, взять и оптимизировать его. И поэтому PostCSS написан на Javascript – в 4 раза быстрее libsass, написанный на С++. Это к вопросу о том, когда бэкендер будет говорить вам о том, что «давайте теперь пишем все на Си, это быстрее», то нет, это не быстрее.
Еще раз: какие преимущества PostCSS, почему оно лучше, чем Sass?
![](https://habrastorage.org/getpro/habr/post_images/c28/674/fa9/c28674fa9a29a1888138853761f21769.png)
- PostCSS гораздо быстрее. Т.е. даже если вы довольны скоростью libsass, используя PostCSS, вы можете сделать больше вещей, вы можете делать какую-то более сложную оптимизацию. Это огромное пространство.
- Вторая вещь – это модульность, вы можете взять и форкнуть проект, вы можете использовать разные идеи.
- А третья вещь – самая важная, что PostCSS больше чем Sass. Вы можете на PostCSS делать любую фичу, которая есть в Sass, но на Sass вы не можете сделать большинство фич, которые есть в PostCSS.
Но я обманул вас. В названии доклада говорилось, что PostCSS – это будущее после Sass. На самом деле, это настоящее. У нас уже прямо сейчас больше полумиллиона загрузок в месяц с Can I Use. Огромная аудитория. Поэтому, если вы боитесь по поводу продакшн-реди, не бойтесь, мы действительно проверяем PostCSS на огромной аудитории. PostCSS пользуются очень большие компании.
![](https://habrastorage.org/getpro/habr/post_images/5ae/07f/a01/5ae07fa018252babff953bffda682ff7.png)
Paul Irish говорил, что автопрефиксер с PostCSS используется в Google. Taobao – это крупнейший Интернет-магазин Китая, он не просто использует PostCSS, разные плагины, он их и пишет. Wordpress использует два плагина. Автопрефиксер rtl css – для арабской версии. И Твиттер не просто использует PostCSS, они в какой-то момент взяли и выкинули Less. У них используют только постпроцессоры. Только этот способ подхода.
![](https://habrastorage.org/getpro/habr/post_images/f8b/9bb/322/f8b9bb322305e64bbcc7884a83a9052e.png)
Кроме того, PostCSS становится трендом. Например, A List Apart написала интересную статью о постпроцессорах, о том, как постпроцессоры PostCSS спасет нас от темной стороны CSS-процессоров (http://alistapart.com/column/what-will-save-us-from-the-dark-side-of-pre-processors).
![](https://habrastorage.org/getpro/habr/post_images/2bf/251/116/2bf251116bde43ca559604625c814761.png)
Или например, перебежчик в наш лагерь, Бен Фрейн автор книги «Sass и Compass для дизайнеров» написал статью о том, как он расставался с Sass и переходил на PostCSS (http://benfrain.com/breaking-up-with-sass-postcss).
![](https://habrastorage.org/getpro/habr/post_images/31d/ac4/a2f/31dac4a2f59ba541221d2e421c4a8080.png)
Но самый клевый твит, это конечное же, Bootsstrap. Они написали, что они настолько вдохновлены CSSnext’ом, им это так понравилось, что Bootstrap 5 скорее всего будет на PostCSS (https://twitter.com/mdo/status/591364406816079873). Сейчас он на Less, потом он будет на Sass, а Sass они собираются выкидывать и переходить на PostCSS.
Т.е. что я хочу, чтобы вы сделали, когда пришли на этих выходных домой?
![](https://habrastorage.org/getpro/habr/post_images/be2/eed/fd9/be2eedfd920aeb325e12c61c9f6a289b.png)
Первый момент: если вы делаете какой-то интересный инструмент для обработки CSS, подумайте о том, чтобы использовать PostCSS. PostCSS гораздо лучше, чем Regexp, потому что Regexp опасный – они изменяют вам карты кода и т.п. вещи.
Второй момент – препроцессоры. Вот, например, еще один перебежчик в наш лагерь – разработчик Grid’а, примеси для реализации сетки lost, который писал Макеев в очень интересном твиттере веб-стандартов, – он перешел на постпроцессоры, ему так понравилось, почему? Потому что раньше было нужно поддерживать три версии – одну для Stylus’а, одну для Less, другую для Sass. Это было очень нудно. А тут он понял: зачем это делать? Он просто возьмет как автопрефиксер. Он взял PostCSS, и его могут использовать пользователи Sass, пользователи Less и т.д.
![](https://habrastorage.org/getpro/habr/post_images/02c/29e/bfa/02c29ebfa72852a08faa04953dd37066.png)
Если вы делаете сайты, делаете инструмент и не используете PostCSS, добавьте автопрефиксер прямо сейчас. Это очень важно, почему? Потому что Google рекомендует единственный инструмент для работы с префиксами. Это только PostCSS, все остальные элементы гораздо хуже, есть много причин почему.
![](https://habrastorage.org/getpro/habr/post_images/f78/d65/f29/f78d65f297edf6ef36745680a02165c3.png)
Третий момент. Если вы уже используете PostCSS, например, для автопрефиксера, посмотрите на другие плагины. Я советую начать с cssnext, потому что он реально клевый, это возможность писать на CSS 4 сейчас. Кроме этого, посмотрите список плагинов, мне кажется, что это понравится.
![](https://habrastorage.org/getpro/habr/post_images/c0c/63c/cf4/c0c63ccf42c46da304adce8f90e45a55.png)
И четвертый момент. Если вы начинаете новый проект, я не рекомендую выкидывать 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);