← Articles

A practical PostCSS approach with Gulp

PostCSS is great, it’s flexible, modular and lets you integrate it into your project the way you want. But using and configuring PostCSS can be somewhat of a challenge at first. I had to dig through a lot of documentation and do even more testing. For me (a front-end developer with a background in design :P), that meant I couldn’t just ‘jump right in’ and start using it.

In this article I want to share the fruits of my journey and help you get started using PostCSS in your project.

In this article I want to share a practical approach to help you set up a PostCSS project which you can actually use. If you like this article and want more indepth information on PostCSS let me know!

If you’re familiar with NPM and Gulp you can skip the first two section and start with section 03. Installing PostCSS.

You can download the source of our example project from Github, we recommend keeping it close so you can refer back to it.

What we will be covering

01. Installing NPM
02. Setting up Gulp
03. Installing PostCSS
04. Add some PostCSS
05. Adding some PostCSS plugins
06. Taking it a bit further
07. Sources


Installing NPM

We’ll be using NPM to install your dependencies like Gulp and of course PostCSS, so lets take care of that first. You need to install Node.js in order to install the NPM package manager. Please check this excellent getting started guide.

Node automatically comes with a version of NPM but it’s usually a good idea to make sure we’ve got the latest version. NPM itself is used to update NPM:

npm install npm@latest -g

The -g means you want to install the package system wide, or [g]lobal.

If you get messages about not having enough permissions do not be tempted to use sudo. Check this page on fixing issues related to permissions.

When the process is finished go ahead a create a new project directory, name it what ever you like, and change directory into it. In your newly created directory execute the following command and answer a couple of questions.

npm init

Enter a project name and Enter through the rest for now. This init command creates a new file (package.json) in your directory where you store a reference for each of the dependencies you will use for this project. In the future anyone who clones or downloads your project will only have to run:

npm install

The dependencies will be installed in your project folder in node_modules/. It is highly recommended that you add this folder to your .gitignore file when you’re using Git.

Now lets get started adding dependencies. :)

Setting up Gulp

While PostCSS comes with a executable you surely want to use a task-runner like Gulp to automate everything so we don’t have to repeat and memorize long commands. You can add Gulp as your first project dependency which will help you save time from the beginning.

npm install gulp --save-dev

The –save-dev flag is important. This will save Gulp in your package.json as a (development) dependency. You can check if it all went well by running cat package.json.

Now create a gulpfile.js in your project folder and add following to it:

'use strict'

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

// array list of plugins 
const postcss_plugins = [];

// the gulp task you can run on your cli as: gulp css:compile
gulp.task('css:compile', function () {
  return gulp.src('./src/styles/main.css')
    .pipe(postcss(postcss_plugins))
    .pipe(gulp.dest('./dist/first-run/'));
});

Create a folder structure and a main.css (src/styles/main.css) and add your own CSS code or copy the code from the Github download. As you can see above in the task definition the target file will be compiled to the ./dist folder.

Try and run gulp css:compile you will get a dependency error, that’s fine we’re going to fix that in the next section.

Installing PostCSS

Now we’re ready to add PostCSS as a dependency to your project. You want to use Gulp for your build so Let’s install PostCSS Gulp:

npm install --save-dev gulp-postcss

Let’s try to run Gulp compile again like you did at the end of the previous section, it gave you an error then let’s see what it does now.

gulp css:compile

Everything should work now, my laptop needed 24ms. Your output should look something like this:

[12:00:00] Starting 'css:compile'...
[12:00:00] Finished 'css:compile' after 24 ms

Go check your .dist/ directory, it now contains an empty CSS file which is expected.

Add some PostCSS

In order to test if PostCSS is working we need to add some CSS syntax. Especially syntax we can really use in order to create a proper postCSS project. I prepared some code below or you can copy the files from the provided repository.

/*! Importing and combining css files */

@import '_vars.css';
@import '_extension.css';

/*! Autoprefixer */

header {
  display: flex;
}

/*! BEM naming convention for nested styles */

.block {
  width: 100%;
  &__element {
    color: var(--primary);
  }
  &--modifier {
    color: var(--secondary);
  }
}
You can see I want to import a _vars.css that contains my PostCSS variables. I want these variables to be accessible globally so I will need to add them to the top. This way other imported css files should also have access.

There are three things I want to test in order to create a PostCSS project i’m comfortable with:

  1. Importing other CSS files
  2. Testing autoprefixer
  3. Using a naming convention like BEM (check Sources below)

If your run the build again (gulp css:compile) there will be no errors. The file will be created in your ./dist folder but it would not be the desired output. The CSS syntax that was parsed would be exacly the same as the CSS syntax we provided earlier.

And this is were PostCSS plugins come in to play. But lets break it down into smaller bits.

Importing other CSS files
We want to add a PostCSS plugin to neatly import other CSS file and merge them in our main CSS file.

Autoprefix our code
We want to add a PostCSS plugin that adds vendor prefixes to our CSS syntax so we can write less code.

We want our CSS code modular and readible
We want to add a PostCSS plugin that knows how to convert BEM naming convention to clean CSS syntax.

Adding some PostCSS plugins

Luckily PostCSS got you covered. We can install these plugins:

npm install --save-dev postcss-easy-import postcss-cssnext postcss-nested
Im using postcss-cssnext as a plugin that has Autoprefixer build into it. CSSNext is a great way of using newer CSS syntax today. It contains helper mixins and functions. Please check Sources below.

Taking it a bit further

So we installed the missing plugins using NPM and we need to add them to our gulpfile.js. I added a second task below our first so we can keep track on the difference between them.

'use strict'

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

// first task

const postcss_plugins = [
];

gulp.task('css:compile', function () {
  return gulp.src('./src/styles/main.css')
    .pipe(postcss(postcss_plugins))
    .pipe(gulp.dest('./dist/first-run/'));
});

// second task

const postcss_plugins_ext = [
  require('postcss-easy-import'),
  require('postcss-cssnext'),
  require('postcss-nested')
];

gulp.task('css:compile_ext', function () {
  return gulp.src('./src/styles/main.css')
    .pipe(postcss(postcss_plugins_ext))
    .pipe(gulp.dest('./dist/second-run/'));
});

You can run a combined command for our two tasks so we can see the difference:

gulp css:compile && gulp css:compile_ext

The two tasks will run and you will get the output below in your cli.

[12:00:00] Starting 'css:compile'...
[12:00:00] Finished 'css:compile' after 25 ms
[12:00:00] Starting 'css:compile_ext'...
[12:00:00] Finished 'css:compile_ext' after 323 ms

You can see that the second task took longer to run. Success! If you check your ./dist directory you will see the files that were parsed and this time the CSS syntax of the second task will have parsed correcly. It imported the CSS files and parsed the variables we declared in our _var.css file.

It added vendor prefixes to our header {} and converted the BEM naming convention to plain CSS syntax.

/*! Importing and combining css files */

/*! Variables */

.extension {
  color: RebeccaPurple;
}

/*! Autoprefixer */

header {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

/*! BEM naming convention */

.block {
  width: 100%
}

.block__element {
  color: RebeccaPurple;
}

.block--modifier {
  color: MediumTurquoise;
}

I hope this guide was useful to you in some way. Please comment, like and share this article. It really helps :)


Sources

NPM starting guide
Gulp
PostCSS
CSSNext
Autoprefixer
BEM naming convention

Please share this post:
Thomas Cremers Mick Schouten
google+facebooktwitterstack overflow