От автора: CSS разработка, как и другие языки, это интерактивный процесс. С каждым обновлением добавляются новые свойства и синтаксис, помогающие нам в написании стилей. В документации CSS Level 3 были представлены свойства, с помощью которых можно создавать интерактивные элементы дизайна, что раньше было возможно только с JavaScript. Каждый день появляются все новые инструменты, упрощающие процесс написания стилей и делающие его более гибким.
Одним из недавних инструментов можно назвать PostCSS. PostCSS заново изобретает CSS, но с добавлением плагинов и сторонних инструментов. Препроцессор работает так же, как и Sass и LESS, трансформирует расширенный синтаксис и свойства в современный и дружелюбный CSS код. А как же JavaScript? — спросите вы.
С помощью JavaScript можно намного быстрее трансформировать стили, нежели с помощью препроцессоров. В таск раннерах типа Gulp или Grunt стили можно трансформировать в процессе создания файла, так же как при компиляции в Sass и LESS. Библиотеки типа React и AngularJS открывают двери для трансформации и написания стилей напрямую через JavaScript.
История PostCSS
Разработчик PostCSS Andrey Sitnik, а также создатель Autoprefixer, сначала разрабатывал препроцессор в качестве метода обработки CSS через JavaScript. По сути PostCSS простое API, но в сочетании со своей огромной экосистемой плагинов предлагает мощные способности. Для процесса отладки генерируются картографические источники, а для понимания того, где и как трансформируется код, существует абстрактное дерево синтаксиса (AST).
Возможности языка по желанию можно легко модифицировать и кастомизировать, так как PostCSS работает на фреймворке Node.js. В других же системах типа Sass или LESS после написания компилятора ограниченное количество методов.
Так как PostCSS работает как API, с его помощью можно создавать свои собственные плагины и инструменты для любых свойств. Эта модульная конструкция платформы делает инструмент абсолютно нейтральным, что позволяет сосредотачиваться на свойствах, требуемых в проекте. PostCSS не привязан к языковому формату, а значит, можно использовать синтаксис других препроцессоров типа Sass, LESS.
Преимущества модульного мышления
Разработчики редко начинают проект с нуля. Многие начинают с Sass шаблона, в котором содержатся переменные, миксины и функции для будущего проекта. У нас же для облегчения производства будут отдельные стили для функций, миксинов, grid систем и основных утилит. В конце статьи мы получим 10 или больше файлов стилей.
Обслуживание библиотеки Sass или LESS сниппетов кода достаточно сложная задача, проект может разрастись. Во многих проектах присутствуют функции и миксины, которые не используются «просто на случай». PostCSS легко устанавливается, имеет plug-and-play модульность, а также делает процесс разработки более гибким под конкретные нужды проекта.
PostCSS перемещает весь код для создания функций, утилит и миксинов из стилей в плагины. Для каждого проекта можно выбирать требуемые инструменты, а также плагины через таск раннер.
Примером может послужить плагин PostCSS FontPath. С помощью Sass можно добавить в файлы миксины, необходимые для кастомных шрифтов; т.е. мы создаем @font-face теги.
1 2 3 4 5 6 7 8 9 10 11 12 |
@mixin importfont($font-family, $font-filename, $font-weight : normal, $font-style :normal, $font-stretch : normal) { @font-face { font-family: '#{$font-family}'; src: url('#{$font-filename}.eot'); src: url('#{$font-filename}.woff') format('woff'), url('#{$font-filename}.ttf') format('truetype'); font-weight: $font-weight; font-style: $font-style; font-stretch: $font-stretch; } } @include importfont('mission script', 'fonts/mission-script-webfont', 300); |
С плагином PostCSS FontPath нам больше не нужно подключать миксины, как сверху. Можно всего лишь написать код ниже, а PostCSS через Grunt или Gulp трансформирует его в необходимый код.
1 2 3 4 5 6 |
@font-face { font-family: 'My Font'; font-path: '/path/to/font/file'; font-weight: normal; font-style: normal; } |
На момент написания статьи доступно более 100 плагинов, с помощью которых можно писать синтаксис будущего CSS, делать сокращения, добавлять расширения и инструменты. Это уже не просто «клевый инструмент», а им пользуются такие компании, как WordPress, Google и Twitter.
Добавление PostCSS
Для трансформации CSS кода можно воспользоваться таск раннерами типа Gulp и Grunt, так как PostCSS написан на JS. Ниже показано, как подключить PostCSS в ваш проект с помощью Gulp и Grunt. Какой именно инструмент использовать не имеет значения, все зависит от личных предпочтений и того, что в данный момент больше подходит проекту.
Заметка: Полные версии Gulp и Grunt доступны на GitHub. Используйте их как стартовые шаблоны и расширяйте по необходимости.
Установка PostCSS с помощью GULP
Если вы совсем не знакомы с Gulp, чтобы быстро вникнуть и начать использовать инструмент, советую вам прочитать статью Callum Macrae Работаем с Gulp. Для установки PostCSS в проект запустите следующую команду в командной строке:
1 |
npm i gulp-postcss -D. |
В файле проекта Gulpfile.js необходимо подключить наш установленный модуль PostCSS и затем использовать его как задачу. Не забудьте обновить пути, куда будут сохраняться трансформированные файлы.
1 2 3 4 5 6 7 |
var postcss = require('gulp-postcss'); gulp.task('styles', function () { return gulp.src('path/to/dev/style.css') .pipe(postcss([])) .pipe(gulp.dest(path/to/prod)) }); |
В командной строке наберите gulp styles для запуска задачи.
Установка PostCSS с помощью GRUNT
Заметка: Если вы не знаете, что такое Grunt, советую прочитать статью Mike Cunsolo Настройка Grunt. Для установки PostCSS в проект забейте следующую команду в терминал:
1 |
npm i grunt-postcss -D. |
После установки плагин необходимо активировать в grunt файле и создать задачу, как показано в коде ниже. Не забудьте обновить значения cwd и dest.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), styles: { options: { processors: [] }, dist: { files: [{ expand: true, cwd: 'dev/', src: ['**/*.css'], dest: 'prod/' }] } } }); // загружаем post-css. grunt.loadNpmTasks('grunt-postcss'); }; |
Чтобы запустить задачу, необходимо набрать grunt styles в командной строке.
Установка плагина
PostCSS сам по себе не самый мощный инструмент; его сила в плагинах. Вы могли заметить уже, что в коде для Gulp и Grunt выше при объявлении задач использовался пустые массивы. В эти массивы можно импортировать плагины PostCSS, те самые функции, которые необходимо подключить.
Список проверенных плагинов можно посмотреть на страничке PostCSS’ GitHub. Как и все NPM пакеты, плагин можно установить через командную строку. Многие плагины не привязаны к конкретным таск раннерам и могут использоваться как расширения PostCSS. К примеру, мы установим плагин PostCSS Focus, добавляющий :focus ко всем hover состояниям.
Для установки пакетов в проект во всех плагинах из примеров ниже необходимо использовать командную строку и NPM.
Пример установки плагина PostCSS
1 |
npm i postcss-focus -D |
Плагины можно передать в метод напрямую; однако для большей чистоты мы создадим массив и передадим его в качестве аргумента. В массиве хранятся require состояния, которые возвращают плагины, которые в свою очередь затем сразу же вызываются. Если вас заинтересовала данная концепция, прочтите статью Функции и объекты первого класса в JavaScript от Ryan Christiani.
1 |
require('postcss-focus')() |
Измененный код для Grunt с по новой созданным массивом processorArray:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var processorArray = [ require('postcss-plugin')() ]; // сожмем для краткости styles: { options: { processors: processorArray }, dist: { src: 'path/to/dev/style.css', dest: 'path/to/prod/style.css' } } |
И код для Gulp:
1 2 3 4 5 6 7 8 9 |
var processorArray = [ require('postcss-plugin')() ]; gulp.task('styles', function () { gulp.src('path/to/dev/style.css') .pipe(postcss(processorArray)) .pipe(gulp.dest('path/to/prod')) }); |
Плагины
После установки плагина и подготовки инструмента к компиляции кода можно использовать сам PostCSS и его плагины. Сначала необходимо создать файл с расширением .css в папке, где будет храниться наш код.
«Стоп! CSS файл?» Да, все верно, CSS файл. Все потому, что PostCSS трансформирует CSS код, и нам не нужно использовать какой-либо другой синтаксис – просто обычный CSS. Если вы работали с препроцессорами, то вам может показаться странным не использовать файлы .sass, .scss, .styl или .less. Но на деле мы же не конвертируем, а трансформируем наш код.
Чтобы начать работать со стилями в наших новых PostCSS плагинах необходимо запустить команды grunt styles и gulp styles соответственно для каждого таск раннера. Обрабатываемый файл CSS пройдет через PostCSS плагин и другие плагины и затем сохранится в специально отведенном месте.
Если вы только новичок в PostCSS, то ниже приведено несколько полезных плагинов с инструкциями по установке и использованию.
Autoprefixer
Написать стили, которые будут работать со всеми возможными браузерами и устройствами крайне сложно, но еще сложнее следить за свойствами, которым нужны вендорные префиксы. К нашему облегчению плагин Autoprefixer сам находит свойства, которым нужны вендорные префиксы. Плагин освобождает нас от унылой работы написания стилей с современными свойствами и заботится о добавлении вендорных префиксов этим свойствам. Как установить плагин через командную строку:
1 |
npm i autoprefixer -D |
После добавления плагина в массив можно создать отдельный массив поддерживаемых браузеров. Список возможных опций можно найти по ссылке Browserslist Github Account. Добавим плагин Autoprefixer в наш препроцессор:
1 2 3 4 |
var processorsArray = [ // убрали лишнее require('autoprefixer')({ browsers: ['last 2 versions', 'ie 6-8', 'Firefox > 20'] }) ]; |
По заданным условиям в объекте вендорные префиксы будут добавляться к любым свойствам и значениям, где они требуются. Пример начального CSS:
1 2 3 4 |
.item { display: flex; flex-flow: row wrap; } |
И после работы плагина:
1 2 3 4 5 6 7 8 9 |
.item { display: -webkit-flex; display: -ms-flexbox; display: -webkit-box; display: flex; -webkit-flex-flow: row wrap; -ms-flex-flow: row wrap; flex-flow: row wrap; } |
Синтаксис будущих версий CSS с помощью CSSNEXT
CSS4 не за горами, а с ним придут и новые функции, такие как встроенные переменные, кастомные медиа запросы, кастомные селекторы и новые псевдо-классы. На момент написания статьи ни одно новое свойство не поддерживается во всех существующих браузерах, однако после одобрения спецификации, они начнут постепенно поддерживаться.
С помощью CSSNext можно трансформировать любое CSS4 свойство в CSS3, который поддерживается в браузерах. Инструмент можно использовать как отдельно, так и в качестве плагина для PostCSS. Еще раз, его можно добавить в массив processorsArray, в котором содержатся плагины PostCSS. Установить плагин через командную строку можно так:
1 |
npm i cssnext -D |
Добавьте плагин в препроцессоры:
1 2 3 4 |
var processorsArray = [ // сократили код require('cssnext')() ]; |
Теперь в изначальном CSS файле можно использовать CSS4 свойства, а PostCSS через таск раннер трансформирует синтаксис таким образом, чтобы он поддерживался существующими браузерами. Когда новые CSS4 свойства станут поддерживаться в браузерах можно будет просто поменять CSS код местами. Изначальный CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// Кастомные переменные :root { --linkColour: purple; } a { color: var(--linkColour); } // кастомные медиа запросы с диапазонами @custom-media --only-medium-screen (width >;= 500px) and (width <= 1200px); @media (--only-medium-screen) { /* стили для средних экранов */ } // кастомные селекторы @custom-selector :--enter :hover, :focus; @custom-selector :--input input, .input, .inputField; a:--enter { /* Enter styles go here */ } :--input { /* Input field styles go here */ } |
И трансформированный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
a { color: purple; } @media (min-width:500px) and (max-width:1200px){ body{ background:#00f; } } a:focus,a:hover{ background:#00f; } .input, .inputField, input{ background:red; } |
Если хотите больше узнать о возможностях плагина CSSNext, на сайте есть специальная площадка для экспериментов. Там вы можете проверить поддерживаемые плагином свойства CSS4.
Синтаксис Sass
Если вы привыкли использовать Sass, не стоит переживать: в PostCSS можно использовать синтаксис Sass и его инструментарий. В то время как обычный CSS еще не поддерживает переменные, наследование и импорт, с помощью плагина PreCSS можно использовать эти функции и писать на синтаксисе Sass в обычном CSS файле.
После добавления плагина через командную строку и добавления на него ссылки на пакет можно сразу же писать на Sass синтаксисе. Если вам понадобится переключиться с Sass обратно в PostCSS, то просто смените расширение обратно на .css и прогоните файл через таск раннер. Установка плагина PreCSS через командную строку:
1 |
npm i precss -D |
Добавляем плагин в препроцессоры:
1 2 3 4 |
var processorsArray = [ // сократили код require('precss')() ]; |
Еще раз, первоначальный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/*Переменные*/ $blue: #0000ff; $green: #00ff00; $radius: 10px; .square { background: $blue; border-radius: $radius; } /*Импорты*/ @import "partials/_base.css"; /*Миксины*/ @define-mixin square $dimension { width: $dimension; height: $dimension; } /*Наследование, переменные и миксины*/ .button { @mixin square 200px; background: $green; &:hover { background: $blue; } } |
И трансформированный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.square { background: #0000ff; border-radius: 10px; } .button { width: 200px; height: 200px; background: #00ff00; } .button:hover { background: #0000ff; } |
Расширяем CSS при помощи плагинов
Плагины позволяют нам писать более эффективный код, основная сила PostCSS как раз в плагинах. С их помощью можно быстрее писать стили или хотя бы быстрее писать необычные стили. Плагины используют PostCSS API и работают с кастомными свойствами, селекторами и значениями, позволяя нам писать более эффективный код, затрачивая меньше времени на Google.
Количественные запросы
Количественные запросы очень мощный инструмент. С их помощью можно подсчитать элементы и применить стили к ним в зависимости от их номера. Само выражение получается достаточно сложным из-за отдельных сложных селекторов. Но количественные запросы можно использовать в CSS уже сейчас. Существуют специальные онлайн сервисы типа QQ, помогающие писать данные запросы. Однако для написания кастомных селекторов можно использовать напрямую PostCSS. Как и любой другой плагин, установите плагин количественных запросов Quantity Queries через командную строку:
1 |
npm i postcss-quantity-queries -D |
Добавьте плагин в список препроцессоров:
1 2 3 4 |
var processors = [ // убрали лишнее require('postcss-quantity-queries')() ]; |
После установки плагина можно использовать кастомные селекторы для добавления стилей для совпадающих элементов. Функция доступна только через плагин. Исходный CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Стили применятся, если будет минимум 5 элементов .container > .item:at-least(5) { background: blue; } // Стили применятся, если элементов не больше 10 .item > a:at-most(10) { color: green; } // Стили применятся, если элементы в диапазоне .gallery > img:between(4, 7) { width: 25%; } // Стили применятся, если элементов будет ровно 4 .profiles:exactly(4) { flex: 1 0 50%; } |
И код на выходе:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// Стили применятся, если будет минимум 5 элементов .container > .item:nth-last-child(n+5), .container > .item:nth-last-child(n+5) ~ .item { background: blue; } // Стили применятся, если элементов не больше 10 .item > a:nth-last-child(-n+10):first-child, .item > a:nth-last-child(-n+10):first-child ~ a { color: green; } // Стили применятся, если элементы в диапазоне .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child, .gallery > img:nth-last-child(n+4):nth-last-child(-n+7):first-child ~ img { width: 25%; } // Стили применятся, если элементов будет ровно 4 .profiles:nth-last-child(4):first-child, .profiles:nth-last-child(4):first-child ~ .profiles { flex: 1 0 50%; } |
Сокращенные свойства с помощью плагина SHORT
Во время написания стилей невольно задумываешься «А тут можно было бы написать и короче». К счастью, у нас есть плагин Short: с его помощью можно писать стили логически. С его помощью можно сократить свойства position и size в одну запись так же, как со свойствами background font.
При помощи PostCSS API сокращенные объявления свойств трансформируются в читаемую браузером форму, позволяя поддерживать порядок в файле стилей и экономить место. Установить Short можно так:
1 |
npm i postcss-short -D |
Добавляем плагин в список препроцессоров:
1 2 3 |
var processors = [ require('postcss-short')() ]; |
Свойство text включает в себя следующие типографские свойства: color, font-style, font-variant, font-weight, font-stretch, text-decoration, text-align, text-rendering, text-transform, white-space, font-size, line-height, letter-spacing, word-spacing и font-family. Исходный код:
1 2 3 |
p { text: 300 uppercase dimgrey center 1.6rem 1.7 .05em; } |
Код на выходе:
1 2 3 4 5 6 7 8 9 10 |
p { color: dimgrey; font-weight: 300; text-align: center; text-transform: uppercase; font-size: 25px; font-size: 1.6rem; line-height: 1.7; letter-spacing: .05em; } |
В свойстве position можно указать сразу четыре значения top, left, right, bottom. Порядок значений по часовой стрелке от 1 до 4. Если одно значение необходимо пропустить, можно поставить *. Исходный CSS код:
1 2 3 4 5 6 7 8 9 10 11 |
section { position: absolute 10px * *; } .topNav { position: fixed 0 * * 0; } .modal { position: fixed 40% 25%; } |
Конечный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
section { position: absolute; top: 10px; } .topNav { position: fixed; top: 0; left: 0; } .modal { position: fixed; top: 40%; right: 25%; bottom: 40%; left: 25%; } |
Какое значение это имеет для нашей индустрии?
Преимущества от PostCSS можно использовать уже сейчас. Точно так же, как при компиляции Sass и LESS, PostCSS можно встроить в проект при помощи таск раннера. Специальные плагины типа PreCSS позволяют портировать существующий Sass проект в PostCSS без необходимости вносить какие-либо изменения.
На момент написания статьи дискуссия по поводу того, в чем же все-таки лучше писать CSS, все еще продолжается. С растущей популярностью таких библиотек как React идея написания стилей прямо в переменной, что в свою очередь позволяет изменять CSS через JS, также растет. Пока что это всего лишь дискуссии, но данный метод уже можно использовать для трансформирования стилей в PostCSS.
Еще один проект, наделавший шума, это CSS Modules. Стили собираются в файлы, которые подключаются по мере необходимости. В JavaScript кругах данная концепция уже крайне популярна. Так как линия между front-end языками типа React and JSX продолжает размываться, становится сложно игнорировать смешанные CSS/JS инструменты.
PostCSS расширяет обычный CSS совершенно новым образом, при помощи кастомного синтаксиса и свойств. Однако для новичков данный инструмент может показаться очень сложным, им для начала хотя бы с обычным CSS освоиться. Если в вашей команде разработчиков есть новички, постарайтесь объяснить им все преимущества PostCSS и принцип его работы. Сделайте так, чтобы они сами захотели изучить PostCSS, чтобы они поняли, как данный инструмент повышает эффективность написания стилей.
Как использовать PostCSS уже сегодня
В течение следующих пары лет сам принцип написания CSS изменится до неузнаваемости. У каждого проекта будут свои требования, под которые мы уже будем находить специальные решения. Работая с такой модульной системой как PostCSS, у нас есть возможность выбирать и подключать функции, которые по нашему мнению пригодятся в проекте.
Я хочу, чтобы вы исследовали мир PostCSS и всех его плагинов. Так как это проект сообщества, то он будет расти только, если люди будут им пользоваться и создавать плагины. Больше плагинов можно найти на сайте NPM по ссылке. А протестировать возможности плагинов на PostCSS площадке.
Автор: Drew Minns
Источник: //www.smashingmagazine.com/
Редакция: Команда webformyself.