Intro To Gulp Part 2 - CSS

GulpJS

In part 1, I went over using Gulp to work with our javascript files. In this entry, I will be going over using it for our SASS/CSS files. So let's go ahead and dive in. Just like before I am going to start with a super simple gulpfile. I will not be using the one we created in the previous lesson because I am going to make everything very modular in my next post.

What we want to do

First, let's write out our list of everything we want our task to accomplish with our CSS. I personally use SASS as a pre-processor so, in my build, I will be working with it.

  • Monitor all our SASS files for changes
  • Compile our SASS files into a single CSS file
  • Make sure vendor prefixes are used when necessary
  • Lint our CSS File
  • Copy our new file into our distribution folder
  • Minify the file
  • Rename the file

So again, let's start with our basic gulpfile:

var gulp = require( 'gulp' );

gulp.task( 'css', function() { 
  gulp.src( './src/css/**/*.scss' ).pipe( gulp.dest( './dist/css' ) );
)};  

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

// The default task (called when you run `gulp` from cli)
gulp.task( 'default', ['watch']);

As before, this handles our first requirement but it simply copies all of our existing SASS files over into our distribution folder. This isn't what we want at all!

SASS to CSS

There is a great plugin for working with SASS inside of Gulp called gulp-sass. Let's go ahead and install it and include it in our gulpfile.

npm install gulp-sass

And our gulpfile:

var gulp = require( 'gulp' );
var sass = require( 'gulp-sass' );

gulp.task( 'css', function() { 
  gulp.src( './src/sass/app.scss' )
     .pipe(sass())
     .pipe( gulp.dest( './dist/css' ) );
)};  

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

// The default task (called when you run `gulp` from cli)
gulp.task( 'default', ['watch']);

There are a couple of changes. We have included our SASS plugin but notice, in the css task, the src option only lists a single SASS file. Although we are monitoring all of our SASS files for changes, when the task runs, it only executes against the one file app.scss.

The reason being, I make one main SASS file that imports all my different component SASS files. For example, I have a "base" SASS files with all my variables, mixins and basic font settings. I might have another called "elements" with different styles for buttons, inputs, etc. So all of these files are being monitored for changes but I only need to compile the app.scss because it includes all of the other files!

Our task uses the sass() call to convert to CSS and copied the resulting file to our distribution folder. Now we can mark these steps off of our list now.

  • Monitor all our SASS files for changes
  • Compile our SASS files into a single CSS file
  • Copy our new file into our distribution folder

Prefixing and Linting

Now let's take care of those pesky vendor prefixes. Before I used gulp, I created a bunch of mixins to add vendor prefixes into my CSS. Not any more! There is a plugin called gulp-autoprefixer that can now do this for us. We can install it the same way we did the SASS plugin.

npm install gulp-autoprefixer

Now let's get it setup in our gulp file.

var gulp = require( 'gulp' );
var sass = require( 'gulp-sass' );
var prefix = require( 'gulp-autoprefixer' );

gulp.task( 'css', function() { 
  gulp.src( './src/sass/app.scss' )
     .pipe( sass() )
     .pipe( prefix('last 3 versions') )
     .pipe( gulp.dest( './dist/css' ) );
)};  

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

// The default task (called when you run `gulp` from cli)
gulp.task( 'default', ['watch']);

Two new lines of code and vendor prefixes are handles. We pass an arument 'last 3 versions' which tells the prefixer to append all the prefixes needed to support the last three versions of all the major browsers. That's freakin' cool right there!

Now, we can take care of linting our code. I used gulp-csslint. Again, you install it the same way as the previous plugins (so I am not going to show this step anymore) and update our file.

var gulp = require( 'gulp' );
var sass = require( 'gulp-sass' );
var prefix = require( 'gulp-autoprefixer' );
var lint = require( 'gulp-csslint' );

gulp.task( 'css', function() { 
  gulp.src( './src/sass/app.scss' )
     .pipe( sass() )
     .pipe( prefix('last 5 versions') )
     .pipe( lint() )
     .pipe( gulp.dest( './dist/css' ) );
)};  

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

// The default task (called when you run `gulp` from cli)
gulp.task( 'default', ['watch']);

Cool! We now see all of our css errors and warnings and can fix them as needed.
Let's mark those off the list.

  • Make sure vendor prefixes are there
  • Lint our CSS File

Minify and Rename

All that is left on our list of requirements is minifying and renaming. First, let's get the minification done. For this I will use gulp-compressor. And, if you read part 1, we used a plugin called gulp-rename to rename our files. This will work on our CSS file as well so let's add them in.

var gulp = require( 'gulp' );
var sass = require( 'gulp-sass' );
var prefix = require( 'gulp-autoprefixer' );
var lint = require( 'gulp-csslint' );
var rename = require( 'gulp-rename' );
var compress = require( 'gulp-compressor' );

gulp.task( 'css', function() { 
  gulp.src( './src/sass/app.scss' )
     .pipe( sass() )
     .pipe( prefix('last 5 versions') )
     .pipe( lint() )
     .pipe( gulp.dest( './dist/css' ) )
     .pipe( compress() )
     .pipe( rename( { suffix: '.min' }) )
     .pipe( gulp.dest( './dist/css' ) )
)};  

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

// The default task (called when you run `gulp` from cli)
gulp.task( 'default', ['watch']);

After this update we are now copying app.css to dist folder, then compressing it and renaming it to app.min.css. That handles all of our requirements! Nice and easy.

  • Minify the file
  • Rename the file

Going Above and Beyond

While researching this, I came across a number of other plugins that i thought would be very useful. Some of them I added to my own workflow and others I plan on experimenting with later on. Here they are

  • SCSSLint - Lints your SASS files before compiling them to CSS.
  • gulp-bless - Gulp plugin which splits CSS files suitably for Internet Explorer < 10
  • csscss - gulp plugin that runs csscss, a CSS redundancy analyzer.
  • group-css-media-queries - CSS postprocessing: group media queries. Useful for postprocessing preprocessed CSS files.
  • gulp-rev - Static asset revisioning by appending content hash to filenames: unicorn.css → unicorn-098f6bcd.css
  • gulp-rev-css-url - The lightweight plugin to override urls in css files to hashed after gulp-rev
  • uncss - Remove unused CSS selectors.
  • critical - Extract & Inline Critical-path CSS from HTML
  • colorguard - Keep a watchful eye on your css colors.
  • livereload - gulp plugin for livereload

That's all for this time. Next time, I will talk about image optimization. And, as an added bonus, combining all of the gulpfiles into one file with a bunch of cool tricks aiming to keep our gulpfile as DRY as possible.

'Til next time,
-G