Preface

Goal: Configure postcss for use with custom spacing classes.

There are many way to configure PostCSS,

  • Using postcss.config.js

  • Using Task Runner such as Grunt and Gulp

  • Using bundler, such as postcss.config.js along with webpack.config.js.

Reading

All code below are ported from the previous SASS article:


1: PostCSS Configuration

There are many way to configure PostCSS. The simple one is using postcss.config.js.

When to Use

This assuming that you do not work with any other tools. If you work with other tools you might consider to use gulp or grunt. Or even postcss.config.js along with webpack.config.js.

Requirement

Requirement may vary, for each case. Some developer might utilize PreCSS, while some other developer might prefer SugarSS. And so does deatil feature for each project might be different.

For the next loop spacing class case, PreCSS is all you need. Also for three good reasons I added some feature:

  • prettier or prettify: to tidy the output CSS,

  • postcss-strip-inline-comments: to enable inline comment style like in SASS, and

  • postcss-each: complex each with mutiple variable.

Example

For this tutorial, I simply use this configuration below:

module.exports = {
  syntax: 'postcss-scss',
  plugins: [
    require('postcss-strip-inline-comments'),
    require('postcss-each'),
    require('precss'),
    require('postcss-prettify'),
  ],
}

Node Package

For this to work, we need package.json:

{
  ...
  "devDependencies": {
    "postcss": "^7.0.29",
    "postcss-cli": "^7.1.1",
    "postcss-each": "^0.10.0",
    "postcss-prettify": "^0.3.4",
    "postcss-scss": "^2.0.0",
    "postcss-strip-inline-comments": "^0.1.5",
    "precss": "^4.0.0"
  }
}

Do not forget to install with NPM.

$ npm install

Command Line Interface

Now you can simply run this command:

$ postcss -d build src/00-comment.css

Or watch in verbose.

$ postcss -w --verbose -d build src/**/*.css
Processing src/00-comment.css...
Processing src/01-for.css...
Processing src/02-for-by.css...
Processing src/03-each.css...
Processing src/04-each-pairs.css...
Processing src/05-for-each-pairs.css...
Processing src/06-for-nested-each-pairs.css...
Processing src/07-final.css...
Processing src/08-final-xy.css...
Finished src/00-comment.css in 1.5 s
Finished src/01-for.css in 1.51 s
Finished src/02-for-by.css in 1.51 s
Finished src/04-each-pairs.css in 1.51 s
Finished src/05-for-each-pairs.css in 1.51 s
Finished src/03-each.css in 1.51 s
Finished src/06-for-nested-each-pairs.css in 1.51 s
Finished src/07-final.css in 1.51 s
Finished src/08-final-xy.css in 1.51 s

Waiting for file changes...

PostCSS: Watch in Verbose


2: Alternative: Gulp

There are many way to configure PostCSS, alternatively you can usegulp. The basic configuration is as below:

Basic Gulp

PreCSS is all you need.

'use strict';

var gulp = require('gulp');

gulp.task('css', () => {
  const postcss    = require('gulp-postcss')

  return gulp.src('src/**/*.css')
    .pipe( postcss([ require('precss') ]) )
    .pipe( gulp.dest('dest/') )
})

gulp.task('default', gulp.series('css'));

Complete Gulp

The code grow as below:

'use strict';

var gulp = require('gulp');

gulp.task('css', () => {
  const postcss    = require('gulp-postcss')
  const prettier   = require('gulp-prettier')
  const scss       = require('postcss-scss');

  return gulp.src('src/**/*.css')
    .pipe( postcss([ 
        require('postcss-strip-inline-comments'), 
        require('postcss-each'),
        require('precss')
      ], {syntax: scss}) 
    )
    .pipe( prettier() )
    .pipe( gulp.dest('dest/') )
})

gulp.task('default', gulp.series('css'));

Node Package for Gulp

For this to work, we need package.json:

{
  ...
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-postcss": "^8.0.0",
    "gulp-prettier": "^2.3.0",
    "precss": "^4.0.0",
    "postcss-scss": "^2.0.0",
    "postcss-strip-inline-comments": "^0.1.5",
    "postcss-each": "^0.10.0"
  }
}

Now you can install with NPM.

$ npm install

Run Gulp, Run!

Now run the gulp:

$ gulp
[01:27:27] Using gulpfile ~/Documents/postcss/gulpfile.js
[01:27:27] Starting 'default'...
[01:27:27] Starting 'css'...
[01:27:34] Finished 'css' after 6.89 s
[01:27:34] Finished 'default' after 6.89 s

Gulp: running PostCSS


3: Alternative: Grunt

Using Grunt with postcss is a little bit tricky, because post css in grunt will overwrite the original files

Luckily there is a cool complete answer in stackoverflow.

Basic Grunt

Consider this my first attempt of Gruntfile.js configuration:

module.exports = function(grunt) {
  // configure the tasks
  let config = {

    postcss: {
      options: {
        map: true, // inline sourcemaps
        syntax: require('postcss-scss'),
        processors: [
          require('postcss-strip-inline-comments'),
          require('postcss-each'),
          require('precss'),
          require('postcss-prettify'),
        ]
      },
      dist: {
        src: 'src/*.css'
      }
    }
  };

  grunt.initConfig(config);

  // load the tasks
  grunt.loadNpmTasks('grunt-postcss');

  // define the tasks
  grunt.registerTask('default', [
    'postcss'
  ] );

};

With this configuration, all files in src/*.css.

Complete Grunt

After reading stackoverflow, I’ve got this working workaround.

module.exports = function(grunt) {
  // configure the tasks
  let config = {

    postcss: {
      options: {
        map: true, // inline sourcemaps
        syntax: require('postcss-scss'),
        processors: [
          require('postcss-strip-inline-comments'),
          require('postcss-each'),
          require('precss'),
          require('postcss-prettify'),
        ]
      },
      dist: {
        files: [
          {
            src: 'dest/*.css'
          }
        ]
      }
    },

    copy: {
      postcss: {
        files: [
          {
            src: 'src/*.css',
            dest: './dest/',
            expand: true,
            flatten: true
          }
        ]
      }
    },

    watch: {
      postcss: {
        files: ['src/*'],
        tasks: ['postcss'],
        options: {
          interrupt: false,
          spawn: false
        }
      },
    }

  };

  grunt.initConfig(config);

  // load the tasks
  grunt.loadNpmTasks('grunt-postcss');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.registerTask('css', ['copy:postcss', 'postcss']);

  // define the tasks
  grunt.registerTask('default', [
    'css', 'watch'
  ] );

};

Node Package for Grunt

For this to work, we need package.json:

{
  ...
  "devDependencies": {
    "grunt": "^1.0.1",
    "grunt-contrib-copy": "^1.0.0",
    "grunt-contrib-watch": "^1.1.0",
    "grunt-postcss": "^0.9.0",
    "postcss-each": "^0.10.0",
    "postcss-prettify": "^0.3.4",
    "postcss-scss": "^2.0.0",
    "postcss-strip-inline-comments": "^0.1.5",
    "precss": "^4.0.0"
  }
}

Now you can install with NPM.

$ npm install

Run Grunt, Run!

Now run the grunt:

$ gulp
[01:27:27] Using gulpfile ~/Documents/postcss/gulpfile.js
[01:27:27] Starting 'default'...
[01:27:27] Starting 'css'...
[01:27:34] Finished 'css' after 6.89 s
[01:27:34] Finished 'default' after 6.89 s

Grunt: running PostCSS


What is Next ?

After this configuration, it is a good time to examine postcss in action. Consider continue reading [ PostCSS - Loop - Spacing Class ].

Thank you for reading.