Set up PostCSS with Gulp

Post CSS Gulp Cheetah Speed

In this tutorial by David Richied from Dust2Life LLC, you’ll set up PostCSS (using Gulp) inside of Vagrant but note that everything in this tutorial also applies if you’re not using Vagrant. The focus will be on setting up PostCSS, but the majority of time will actually be spent setting up Gulp.  Don’t worry! Gulp is incredibly useful and fun to use. Don’t waste another minute! Start using PostCSS, today.

As a quick preface, I am using Vagrant with Varying Vagrant Vagrants (a Vagrant box optimized for WordPress), but everything will work outside of Vagrant. However, if you are a WordPress developer who is using or wants to use Vagrant, now, would be the perfect time to start. Take a look at this tutorial on setting up Vagrant and VVV and then come right back here to start using PostCSS!

Installing NodeJS into VVV

As mentioned by Jordan, below, before Gulp will work in VVV, you have to install NodeJS. To install NodeJS in Vagrant, navigate to your VVV installation cd ~/vagrant-local, start up Vagrant vagrant up, and enter your Vagrant machine vagrant ssh. After that, run curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash - and sudo apt-get install -y nodejs. See the documentation on Github for NodeJS for more information.

Installing Gulp into Vagrant (Or Anywhere)

The next thing you are going to need to do is provision Vagrant with Gulp. If you are not using Vagrant, simply run npm install gulp -g to install gulp globally. If you are using Vagrant, navigate to ~/vagrant-local (the folder where you downloaded VVV if you have been following the previous tutorials) and then to a folder called “provision”: cd vagrant-local/provision. Now, if a file called “provision-pre.sh” doesn’t already exist, create it inside of the “provision” folder. Next, add the following (probably unorthodox code) to that file.

# gulp install
gulp_install="$(npm list gulp-cli)"
if [ "$gulp_install" = true ]; then
  echo "gulp installed"
else
  echo "gulp not installed"
  npm install --global gulp-cli

fi

After that, open up your terminal, navigate back to vagrant-local, and run vagrant provision

Enabling Gulp for Your Project

Next, navigate to your project’s root folder. The project’s root folder is where you keep everything: your index.html, your js folder, etc. For me, it’s vagrant-local/my-wordpress-install/wp-content/themes/my-theme. From now on, I’ll refer to this directory as the root folder. Run npm init inside of your root folder. This will create a package.json file which you’ll use to enable Gulp. Running npm init will give you a few prompts. My guess is that you will have some questions about what answers to give those prompts. This tutorial on setting up your first NPM package will help.

After that, run npm install gulp --save-dev inside of your root folder. This will save gulp as a dependency for the project. A folder will be created inside of your root folder called node_modules, and gulp will be added to it.

Now, create a file called gulpfile.js in your root folder. At some point, if an error about promises comes up, see this question on Stackoverflow about gulp and the promise error for more information. To fix the problem, I ran npm install es6-promise (inside of Vagrant) and added require('es6-promise').polyfill(); to the top of gulpfile.js that I created in the root folder.

Add var gulp = require('gulp'); to the top of gulpfile.js. This will allow your project to use the gulp package that was just added to the node_modules folder by npm.

Installing PostCSS and Plugins into the Project

Run the following in your root folder to add PostCSS and its plugins to the node_modules folder.

npm install --save-dev gulp-postcss
npm install --save-dev gulp-concat
npm install autoprefixer --save-dev
npm install cssnext --save-dev
npm install precss --save-dev

Now, you should see a couple more folders in your node_modules folder.

Add the following to gulpfile.js. This will allow your project to use the plugins that were just added to the node_modules folder.

var postcss = require('gulp-postcss');
var concat = require('gulp-concat');
var autoprefixer = require('autoprefixer');
var cssnext = require('cssnext');
var precss = require('precss');

Now, inside of your root folder, create one folder named src and another named dest.

Creating the Gulp Tasks

To create a task (a function) in gulpfile.js that will make use of the plugins and join all of the css files in your src directory into one file called style.css, add the following to the bottom of gulpfile.js. If you want your compiled CSS files to their respective files, just remove

.pipe(concat('style.css'))

We’ll call the task “css”.

gulp.task('css', function () {
  var processors = [
	autoprefixer,
  	cssnext,
  	precss
  ];
  return gulp.src('./src/*.css')
    .pipe(postcss(processors))
    .pipe(concat('style.css'))
    .pipe(gulp.dest('./dest'));
});

This task grabs all the stylesheets in your src folder, sends them to each of the processors and, finally, sends the compiled results to the dest folder.

If you are using WordPress (whether in Vagrant or not), all you have to do is change .pipe(gulp.dest('./dest')) to .pipe(gulp.dest('./')). Now, instead of updating a style.css file in a folder called “dest”, it will update a file called style.css in your root folder.

And here’s what the file gulpfile should look like.

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var concat = require('gulp-concat');
var autoprefixer = require('autoprefixer');
var cssnext = require('cssnext');
var precss = require('precss');
gulp.task('css', function () {
  var processors = [
	autoprefixer,
  	cssnext,
  	precss
  ];
  return gulp.src('./src/*.css')
    .pipe(postcss(processors))
    .pipe(concat('style.css'))
    .pipe(gulp.dest('./dest'));
});
gulp.task('watch', function() {
	gulp.watch('src/*.css', ['css']);
});

Now, add a file called style.css to the src folder and add the following CSS to it (something I grabbed from one of my projects). It will make use of PostCSS’s nesting capabilities.

.site-header {
	background-color: rgb(51,51,51);
	width: 100%;
	.wrap {
		max-width: 1200px;
		margin: 0 auto;
	}
}

Finally, in your terminal (inside of your root folder), run gulp css to compile the code. **Warning** If you are using WordPress, first, copy the contents of your style.css file to the style.css file in the “src” file you just created. Running gulp css overwrites everything in the destination CSS file, and you want to make sure you have all of the original contents of your WordPress’s style.css file inside of the style.css file in your “src” folder before compiling. If everything went accordingly, you should now have a file in your dest folder (or root folder) also called style.css with the following compiled code.

.site-header {
	background-color: rgb(51,51,51);
	width: 100%;
}
.site-header .wrap {max-width: 1200px;margin: 0 auto;}

Notice how it took your nested CSS and broke it out into two separate rules.

Congratulations! Your workflow is becoming faster and faster!

What Features Do I Use the Most?

Nesting

Nesting (what I did above) is a huge time saver and a great way to create blocks of CSS that only affect certain elements. For example, let’s say I have a div like 

<div class="amazing-div">Contents</div>

Using PostCSS, I can wrap all of my rules with “.amazing-div” which means that .amazing-div will be appended to every rule inside of it.

.amazing-div {
    .div-in-amazing-div {
        //stuff
    }
}

Importing

This is another great way to modulize (I’m surprised this isn’t a word) your CSS. For example, you can take all the CSS for your header, place it in a file called header.css (inside the same folder as src/style.css), and, add the line import "header.css" to src/style.css. But, wait, you might say, doesn’t adding import statements to you CSS file hurt performace? NO! Because src/style.css and every file it imports is compiled into one file: dest/style.css. The browser doesn’t have to do any importing!

Browser Prefixes

I don’t even have to think about this one. All I have to do to use this feature is ignore browser prefixes and save time! PostCSS adds all the necessary browser prefixes to your CSS. I am amazed how much PostCSS is doing for me. It kind of makes me feel like a professional CSSer.

*BONUS*

It would be a pain to have to run gulp css every time you want to see a change that you made to style.css. Add the following to the bottom of gulpfile.js to allow you to watch changes to the files in your src folder.

gulp.task('watch', function() {
	gulp.watch('src/*.css', ['css']);
});

Now, if you run gulp watch, the style.css file in your dest folder will be updated every time you save any of the CSS files in your src folder.

Recommended reading.

I highly recommend you take a look at this tutorial on setting up Gulp. It does not go over PostCSS, but it is very helpful in understanding Gulp better.