PostCSS – будущее CSS
Веб-среда решительно эволюционирует. Проекты становятся все сложнее, количество используемых технологий неуклонно растет. Построить современный веб-сайт без средств автоматизации уже не представляется возможным. В сообществе разработчиков регулярно появляются новые инструменты — набирая популярность.
Первая версия SASS была выпущена в 2007, Less в 2009, а Stylus в 2010. За это время метаязыки CSS приобрели большую популярность. Редкий проект обходится без их использования. Они позволяют быстро писать кросс-браузерный CSS, сводя к минимуму дублирование кода и автоматизируя рутинную работу.
Но всегда есть то, что можно автоматизировать еще. Тут большую гибкость проявляет подход, используемый в пост-процессорах. И у PostCSS есть ряд преимуществ:
- Скорость работы. Работает в 3 раза быстрее чем libSaas написаный на C++
- Использование будущих возможностей CSS. PostCSS распарсит и адаптирует ваш код.
- Множество плагинов расширяют возможности PostCSS.
Один из известных постпроцессоров Autoprefixer. Он парсит CSS и добавляет вендорные префиксы с caniuse.com. И больше не надо думать какой браузер, на какое свойство использует префикс.
Использование
Для того, чтобы начать пользоваться PostCSS, нужно добавить его в свой любимый сборщик и указать плагины. Я использую Gulp и вот конфиг для него:
gulp.task('css', function () {
var postcss = require('gulp-postcss');
return gulp.src('src/**/*.css')
.pipe( postcss([ require('cssnext')(), require('cssnano')() ]) )
.pipe( gulp.dest('build/') );
});
Примеры работы плагинов
POSTCSS-COLOR-HEX-ALPHA
Вот пример использования синтаксиса будущего CSS уже сегодня. Нотация вида #0000ffcc будет преобразована к виду rgba();
input.css:
body {
background: #9d9c
}
output.css:
body {
background: rgba(153, 221, 153, 0.8)
}
POSTCSS-CUSTOM-MEDIA
И еще один пример из черновика спецификации CSS. Кастомные медиазапросы.
input.css:
@custom-media --small-viewport (max-width: 30em);
@media (--small-viewport) {
/* styles for small viewport */
}
output.css:
@media (max-width: 30em) {
/* styles for small viewport */
}
POSTCSS MIXINS
PostCSS так же предлагает отличные возможности по применению миксинов. Вот простой пример:
input.css:
@define-mixin icon $network, $color: blue {
.icon.is-$(network) {
color: $color;
@mixin-content;
}
.icon.is-$(network):hover {
color: white;
background: $color;
}
}
@mixin icon twitter {
background: url(twt.png);
}
@mixin icon youtube, red {
background: url(youtube.png);
}
output.css:
.icon.is-twitter {
color: blue;
background: url(twt.png);
}
.icon.is-twitter:hover {
color: white;
background: blue;
}
.icon.is-youtube {
color: red;
background: url(youtube.png);
}
.icon.is-youtube:hover {
color: white;
background: red;
}
А вот более интересный пример использования возможностей JavaScript в PostCss. Данный миксин принимает в качестве аргумента директорию с изображениями, и создает для каждого файла свой стиль. При этом называя его в соответствии с именем файла без расширения.
Вот его код:
require('postcss-mixins')({
mixins: {
hb icons: function (mixin, dir) {
fs.readdirSync('/images/' + dir).forEach(function (file) {
var icon = file.replace(/\.svg$/, '');
var rule = postcss.rule('.icon.icon-' + icon);
rule.append({
prop: 'background',
value: 'url(' + dir + '/' + file ')'
});
mixin.replaceWith(rule);
});
}
}
});
И в результате выполнения:
@mixin icons signin;
Получаем:
.icon.icon-back { background: url('signin/back.svg') }
.icon.icon-secret { background: url('signin/secret.svg') }
Кроме того, миксины можно удобно хранить в отдельном каталоге. Для этого в gulpfile.js необходимо прописать mixinsDir:
require('postcss-mixins')({
// 'mixins' - каталог с миксинами
mixinsDir: path.join(__dirname, 'mixins')
})
Теперь складываем наши миксины в каталог mixins. Название файла будет равно названию миксина.
Вот пример с clearfix:
module.exports = {
'&::after': {
content: '""',
display: 'table',
clear: 'both'
}
}
Уже написано достаточное количество плагинов, все их можно посмотреть на сайте с удобным поиском – [http://postcss.parts/](http://postcss.parts/). Делюсь теми, которые я с интересом попробовал и теперь активно использую:
