PostCSS

Введение

PostCSS — программа, которая автоматизирует рутинные операции с CSS с помощью расширений, написанных на языке JavaScript.

Используется при разработке Википедии, Facebook и GitHub.

Один из самых часто загружаемых с npm инструментов для работы с CSS. Разработана Андреем Ситником в компании «Злые марсиане».

Я пользуюсь PostCSS вместе с Gulp, изучить Gulp 4 Вы можете в моей статье Gulp 4

Содержание статьи:
Введение
Установка
Переменные в CSS (postcss-simple-vars)
Импорт файлов CSS (postcss-simple-vars)
Mixins
Видео о PostCSS
Ошибки

Установка PostCSS

Установим PostCSS пакет для Gulp

npm install gulp-postcss --save-dev

Сразу же добавим один из самых популярных плагинов для PostCSS - autoprefixer

Некоторые разработчики пользуются одновременно SASS и PostCSS именно ради этого плагина.

npm install autoprefixer --save-dev

Добавим в gulpfile.js postcss = require('gulp-postcss'), autoprefixer = require('autoprefixer')

А также убедимся, что autoprefixer и gulp-postcss добавились в devDependencies в файле package.json

"devDependencies": { "autoprefixer": "^9.6.1", "browser-sync": "^2.26.7", "gulp": "^4.0.2", "gulp-postcss": "^8.0.0", "gulp-sass": "^4.0.2" }

Отредактируем файл gulpfile.js мы добавили postcss и autoprfixer уберем sass и если что-то было лишнее - тоже уберём.

Для тренировки переименуем функцию style в styles - в скольки местах нужно будет это сделать?

Мы пока что установили только autoprefixer, поэтому сбор нескольких файлов в один нам пока не доступен. укажем исходный файл явно

const gulp = require('gulp') , postcss = require('gulp-postcss'), autoprefixer = require('autoprefixer'); gulp.task('default', function(done) { console.log("Gulp is running!"); done(); }); function styles() { console.log("style is running!"); // 1. where is my dev css files return gulp.src('./app/assets/styles/style.css') // 2. pass that file through postcss compiller .pipe(postcss([autoprefixer])) // 3. where do I save the compiled CSS? .pipe(gulp.dest('./app/temp/styles/style.css')) } function html() { console.log("Some change in index.html happened!"); } function watchFiles() { gulp.watch("./app/assets/index.html", html); gulp.watch("./app/assets/styles/**/*.css", styles); } exports.styles = styles; exports.html = html; exports.watch = watchFiles;

Запустим наш новый watch

gulp watch

Теперь, если мы создадим свойство, которое нуждается в автопрефиксе, например columns и сохраним файл

body {     padding: 27px;     margin: 12px;     columns: 300px 2; }

На выходе - в папке heiheiru/app/temp/styles/style.css мы увидим

body {     padding: 27px;     margin: 12px;     -moz-columns: 300px 2;          columns: 300px 2; }

Если у Вас появились сложности - изучите решение ошибки с path

Переменные в css

Установим пакет postcss-simple-vars

$ npm install postcss-simple-vars --save-dev

npm WARN heihei@1.0.0 No description
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ postcss-simple-vars@5.0.2
added 1 package from 1 contributor and audited 10643 packages in 7.83s
found 0 vulnerabilities

Добавим новую константу

cssvars = require('postcss-simple-vars');

И вставим её в pipe функции styles

.pipe(postcss([cssvars, autoprefixer]))

Теперь можно смело добавить в heiheiru/app/assets/styles/style.css переменные.

Например, цвета. Мне нужно задать основной цвет для раздела о Финляндии. Назовём его finBlue и сделаем таким же как синий во флаге Финляндии.

$finBlue: #002f6c; body { color: $finBlue; padding: 27px; margin: 12px; columns: 300px 2; }

Перезапустим watch и сохраним файл.

Посмотрим, что будет на выходе в папке heiheiru/app/temp/styles/style.css

$finBlue: #002f6c; body { color: #002f6c; padding: 27px; margin: 12px; -moz-columns: 300px 2; columns: 300px 2; }

Как видите, значение из переменной успешно получено и никакого неотносящегося к CSS кода на выходе нет - такой файл можно смело выкладывать на хостинг.

Какой хостинг выбрать - читайте в моей статье Выбор хостинга для сайта

Какой хостинг выбрать

Вложенные теги CSS (nested css)

Для удобства разработчиков создано много плагинов, которые позволяют делать вложенные теги, например создать класс и прямо внутри {написать свойства разных элементов}

В PostCSS за это отвечает плагин postcss-nested

$ npm install postcss-nested --save-dev

npm WARN heihei@1.0.0 No description
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ postcss-nested@4.1.2
added 5 packages from 6 contributors and audited 10659 packages in 12.936s
found 0 vulnerabilities

Добавим в gulpfile.js

nested = require('postcss-nested'); .pipe(postcss([cssvars, nested, autoprefixer]))

А в heiheiru/app/assets/styles/style.css добавим

.box { a { display: block; padding: 10px; } }

Это не валидный CSS, но после обработки PostCSS он превратится в

.box a { display: block; padding: 10px; }

Импорт CSS файлов

Во время разработки сайта удобно иметь небольшие отдельные файлы для каждого блока.

С другой стороны на хостинге лучше иметь один файл style.css, чтобы вебсервер делал меньшее количество обращений к файлам и время загрузки уменьшалось.

Включать несколько файлов в один умеет postcss-import

$ npm install postcss-import --save-dev

npm WARN heihei@1.0.0 No description
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ postcss-import@12.0.1
added 3 packages from 2 contributors and audited 10676 packages in 8.49s
found 0 vulnerabilities

Добавим в gulpfile.js

cssImport = require('postcss-import');

и

.pipe(postcss([cssImport, cssvars, nested, autoprefixer]))

cssImport нужно поставить в самое начало pipe, чтобы PostCSS сперва собрал все модули, а уже потом начал обрабатывать.

Для поддержания порядка в файлах создадим в папке heiheiru/app/assets/styles подпапку modules.

Разместим там файл _topmenu.css

В файле heiheiru/app/assets/styles/style.css напишем

@import "modules/_topmenu";

Mixins

Миксины нужны для удобства разработки адаптивных сайтов. Можно обойтись без них и просто писать везде

@media screen and (max-width: 360px) and (min-width: 310px)

Но с миксинами мне кажется проще. Можете сами попробовать и сравнить.

npm install postcss-mixins --save-dev

npm WARN heihei@1.0.0 No description
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

+ postcss-mixins@6.2.2
added 20 packages from 45 contributors and audited 12743 packages in 19.791s
found 0 vulnerabilities

Добавим новую переменную

const mixins = require('postcss-mixins');

И добавим в pipe postcss mixins

function css() { console.log('MY_LOG: css function is running'); return src('./app/assets/styles/style.css', {base: './app/assets/styles'}) .pipe( sourcemaps.init() ) .pipe(postcss([cssImport, mixins, nested,autoprefixer,cssvars,cssnano])) .on('error', function(errorInfo){ console.log("MY_LOG: postcss Failed"); console.log(errorInfo.toString()); this.emit('end'); }) .pipe( sourcemaps.write('.') ) .pipe(gulp.dest('./dist')) .pipe(gulp.dest('./preFtp/css')); }; exports.css = css;

Создадим отдельный файл _mixins.css и не забываем импортировать его в style.css

@import "base/_mixins";

Определимся сколько диапазонов ширины нужно. Если Вы уже делали адаптивные сайты, то знаете сколько какому сайту нужно. Синтаксис media такой-же как в css

Не забудьте вставить внутрь каждой media query @mixin-content;

@define-mixin atSmall { @media (min-width: 500px) { @mixin-content; } } @define-mixin atMedium { @media (min-width: 501px) and (max-width:1000px){ @mixin-content; } } @define-mixin atLarge { @media (min-width: 1001px) and (max-width:1840px){ @mixin-content; } } @define-mixin atXL { @media (min-width: 1841px) { @mixin-content; } }

В данном примере используется подход Mobile First, то есть по умолчанию стили будут для мобильного телефона.

Видео о PostCSS

Ошибки

No PostCSS Config found in

Скорее всего эта ошибка появилась в результате исплоьзования Postcss с Gulp без sourcemaps

Например был такой код:

gulp.task('serve', function() { gulp.watch("./app/**/*.css", series(css)) console.log('MY_LOG: serve function is running'); }); function css() { console.log('MY_LOG: css function is running'); return gulp.src('./app/assets/**/*.css') .pipe(postcss()) .pipe(gulp.dest('./dest')); }; exports.css = css;

А в спецификации к Postcss сказано, что при использовании с Gulp нужно также добавить sourcemaps. Читать спецификацию

Использование Postcss и Gulp 4

Поэтому код должен выглядеть примерно так:

const sourcemaps = require('gulp-sourcemaps'); function css() { console.log('MY_LOG: css function is running'); return gulp.src('./app/assets/**/*.css', {base: './app/assets'}) .pipe( sourcemaps.init() ) .pipe(postcss([cssImport, nested,cssvars,autoprefixer ])) .pipe( sourcemaps.write('.') ) .pipe(gulp.dest('./dest')); }; exports.css = css;

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@eth1.ru если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: