Cascading Style Sheets (CSS)

A Front-end Build Task With A Living Style Guide, Part 1: SCSS

At Metal Toad our front-end build is important to us. It helps us keep standards consistent and improves the quality of our projects.


At Metal Toad our front-end build is important to us. It helps us keep standards consistent and improves the quality of our projects.

My hope is to show you how you can create your own front-end build by stepping you through how we created ours. In this blog post we will create a Sass compiler. In later posts we will go deeper until we have a comprehensive build that takes care of most of the heavy lifting of front-end work. In addition to Sass compiling we will add a production + development task, SVG build, hot reloading, JavaScript compiler, image compression, Mac notifications, and a living style guide. We will use Gulp.

If you don’t have experience with Gulp I’m not going to go over what it is or how it compares to other build scripts, there is enough info on that. If you need to get setup with Gulp there is already great documentation on how to get setup with Gulp on Github.

Create your gulpfile

Let’s get started. Create a folder for your project and in that folder put a gulpfile.js file. Now let’s install Gulp with NPM.

In your console go to the base folder of your project and run npm install gulp --save-dev

Place the following code in your gulpfile.js:

    
// Required packages 
var gulp = require('gulp');

You will need a package.json. The package.json only needs to be the most basic json file which is {} or you can create one by using npm init in your console.

Create your folder structure

Everyone has different preferences for how they like to organize their projects. That is why we will make the Gulp file easy to change with variables. For this project our folder structure will look like:

    
|-- src/
|   |-- css/
|        |-- app.css
|   |-- dest/
|   |-- styles/
|        |-- styles.css
|-- gulpfile.js
|-- package.json

The src folder will be the folder you work in and the dest folder is where Gulp will move, compile, and compress files and assets to.

Let’s make some variables for these folders in our Gulp file. This way if we need to change the names of folders or where they are located we only need to change them once. Under your imports make the following variables. You can have them point to whatever your structure looks like.

    
// Variables for folder paths source
sourceDir = './src/'; 
destDir = './dest/'; 
stylesSrc = sourceDir + 'styles/**/*.scss'; 
stylesDest = destDir + 'css/';

Install dependencies

We should have already created a package.json when you worked through Gulp's documentation. As we install dependencies we will use the --save-dev command to add it to the package.json. This will allow anyone else who pulls your repo to install all the dependencies they need by simply typing npm install in their console.

In your console let’s install all the dependencies will need for the Sass build task

  • npm install gulp-sass --save-dev
  • npm install gulp-sourcemaps --save-dev
  • npm install gulp-postcss --save-dev
  • npm install autoprefixer --save-dev
  • npm install gulp-clean-css --save-dev
  • npm install gulp-notify --save-dev

Compile Sass task

Here we will build a basic Sass task and we will continue throughout this tutorial building and improving on this task. In this step our goal is to compile Sass for development. We will need sourcemaps so that we know where the rules are located in our .scss files when using the web inspector. We don’t want to worry about browser prefixes when this is something we can automate so we will need something that automates prefixing.

The first thing we will need to do is make sure Gulp knows that the dependencies we installed in the last section are required. We do this at the top of the Gulp file with:

    
var gulp = require('gulp'); 
var sass = require('gulp-sass'); 
var sourcemaps = require('gulp-sourcemaps'); 
var postcss = require('gulp-postcss'); 
var autoprefixer = require('gulp-autoprefixer’); 
var notify = require('gulp-notify');

Now let’s write our first task:

    
gulp.task('sass', function() {
    return gulp.src(stylesSrc)
        .pipe(sass())
        .pipe(gulp.dest(stylesDest))
});

This will compile your app.scss to app.css and move it to your dest/css folder. Try it now by using the command gulp sass in your console.

Great! Now let’s add some bells and whistles.

Sourcemaps will give you the power to use Sass in the browser’s web inspector. You will be able to tell where styles are defined in your file structure when inspecting elements before the styles were compiled. You can even edit your Sass in your web inspector, if you want to get fancy. We will have to initialize the sourcemaps with .pipe(sourcemaps.init()) and then write them before we move the styles with .pipe(sourcemaps.write('.')).

    
gulp.task('sass', function() {
    return gulp.src(stylesSrc)
        .pipe(sourcemaps.init())    
        .pipe(sass())
    .pipe(sourcemaps.write('.'))        
        .pipe(gulp.dest(stylesDest))
});

PostCSS’s goal is to allow you to use the CSS of tomorrow today. We will only be using autoprefixer which adds vendor prefixes to CSS rules. It will use the data based on current browser popularity and property support to apply prefixes for you. No more prefix worries!

We just need to pipe the task through autoprefixer after Sass is written.

    
gulp.task('sass', function() {
    return gulp.src(stylesSrc)
        .pipe(sourcemaps.init())    
        .pipe(sass())
    .pipe(sourcemaps.write('.'))        
        .pipe(gulp.dest(stylesDest))
});

Now we have a pretty good build task but what if something goes wrong? We can easily receive compiling errors in our console. We just need to tell gulp-sassto do this by simply adding .on('error', sass.logError)). If we don’t have our console open though we will never be notified that an error actually happened. This can be super annoying if you are wondering why a style isn’t working for 20 minutes only to realize that you forgot a comma because your Sass isn’t compiling. This is why we use gulp-notify to send a native Mac notification whenever there is an error.

We will make a function that outputs our errors to a Mac notification:

    
function handleErrors(error) {
    notify().write(error);
    console.log(error);
}

So all together:

    
// Required packages
var gulp         = require('gulp');
var sass         = require('gulp-sass');
var sourcemaps   = require('gulp-sourcemaps');
var postcss      = require('gulp-postcss');
var autoprefixer = require('autoprefixer');
var notify       = require('gulp-notify');
 
// Variables for folder paths
sourceDir   = './src/';
destDir     = './dest/';
stylesSrc   = sourceDir + 'styles/**/*.scss';
stylesDest  = destDir + 'css/';
 
function handleErrors(error) {
  notify().write(error);
  console.log(error);
}
 
gulp.task('sass', function() {
  return gulp.src(stylesSrc)
      .pipe(sourcemaps.init())
      .pipe(sass().on('error', handleErrors))
      .pipe(postcss([autoprefixer({
          browsers: ['last 2 versions']
      })]))
      .pipe(sourcemaps.write('.'))
      .pipe(gulp.dest(stylesDest))
});

Great! Now we have a solid gulp Sass task. Although we have to run this task everytime we want to update the CSS and reload the browser everytime we want to make a change. We also need to manually compress our CSS and remove our sourcemaps so that the CSS is production ready. In the next series we will add hot reloading and create two tasks gulp dev and gulp prod. It will be grand.

Similar posts

Get notified on new marketing insights

Be the first to know about new B2B SaaS Marketing insights to build or refine your marketing function with the tools and knowledge of today’s industry.