Adding Grunt to an Existing Compass Project

Grunt is super cool. Compass is super cool. These tools both automate things for you, which is awesome. The only thing even awesomer? Putting the two together.

Who Should Read This Tutorial and How to Get Started

This tutorial is about how to add some Grunt goodness to a pre-existing Compass project. It’s assumed you’re in the know about Compass and at least have an idea about what Grunt does. If not, visit the Compass website or the GruntJS website, or both, to learn more.

Another pre-requisite is that you have Node and NPM (Node Package Manager) installed. Similar to Ruby, depending on your development environment this might be super easy or a bit tricky. Visit the NodeJS website for download and installation instructions. If you have trouble with that, and you’re using Ubuntu and possibly ZSH, try out my Yeoman: Getting it to Work on Ubuntu tutorial and read the section on Node there.

The Existing Compass Project

You have an existing Compass project. That alone does some cool things that some people also use Grunt to do, like minifying CSS and watching for changes to your Sass code. Still, Grunt is helpful even on a Compass project, because it can do things like concatenate and minify your JavaScript, optimize images, etc. We’re going to have Grunt take over the Sass compiling and CSS minifying tasks.

Getting Grunt & Compass Ready for the Dance

Get started by navigating to the directory for your Compass project. In the root directory of the project, create a file named “package.json” and add the following:

{
   "name": "project-name",
   "version": "0.1.0",
   "devDependencies": {
      "grunt": "~0.4.1"
   }
}

Change the name of the project to whatever you want, it doesn’t really matter. Leave the rest of that stuff alone.

In your terminal, run the following command:

npm install

This command installs Grunt into your project directory. If you weren’t previously using Grunt for anything and therefore haven’t gotten it installed yet, type this into the terminal next:

npm install -g grunt-cli

That command installs the command line tool for Grunt and makes it available for you to use in any project. Since I already had Yeoman installed, this wasn’t necessary for me. You can try moving forward without this and then run the command if you get a “command not found” error.

Now, you will need to make a Grunt file. In the root of the project directory, make a “Gruntfile.js” file and add this code:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        // configuration goes here

    });

    // some task setup will go here
};

This configuration file is just a skeleton at this point. We have to install some Node modules before putting anything cool in here.

Install Grunt-Contrib-Compass

Grunt uses Node modules to perform its various tasks. There is no definitive list of tasks Grunt can or cannot run… it’s all dependent on what modules are available. At minimum, you need grunt-contrib-compass installed if you want Grunt to take over Sass compiling duties.

npm install grunt-contrib-compass --save-dev

This command saves the module to your project. Now to use it, you need to set up some configuration in Gruntfile.js:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        compass: {
            dist: {
                options: {
                    config: 'config.rb'
                }
            }
        },

    });

    grunt.loadNpmTasks('grunt-contrib-compass');

    grunt.registerTask('default', ['compass']);
};

The “compass” block in Gruntfile.js is the configuration for the grunt-contrib-compass module. In a new Compass project, you can write the configuration of the Compass project itself into this block, but for an existing project, we’re just telling it to look at your config.rb file. The path is relative to the root of the project.

Loading the module takes place next, in the line that begins with “grunt.loadNpmTasks.” This is how you load any Grunt module into Gruntfile.js for use. Once that line is in there, and the above configuration block is correct, you can type “grunt modulename” into the terminal to run that task.

We want the “compass” task to run every time we type “grunt” into the terminal, so the next line registers a default task list with “compass” being the first entry. This is just an array, and you can add more tasks in there, which we’ll do later.

Save Gruntfile.js and test the configuration out by typing this command in the terminal (at your project root):

grunt

Grunt and Compass
When it works like it should, you will see that it compiled your Sass files. This is the equivalent of running:

compass compile

[note: Yeah, you should really not be watching the compass project in another terminal window or tab somewhere. If that stuff is still running, exit out of it.]

Install Grunt-Contrib-Watch

Now for the “watch” part. It’s fine to compile Sass using Grunt, but you wouldn’t want to give up the “watch” command that comes with Compass. Grunt can watch everything in your project, Sass files included, and perform the tasks you assign it. You will need to install grunt-contrib-watch for this.

Installation is the same as before:

npm install grunt-contrib-watch --save-dev

There you go. Now for the Gruntfile.js additions:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        compass: {
            dist: {
                options: {
                    config: 'config.rb'
                }
            }
        },

        watch: {
            scripts: {
                files: ['sass/*.scss', 'js/*.js'],
                tasks: ['compass'],
                options: {
                    spawn: false
                },
            }
        }

    });

    grunt.loadNpmTasks('grunt-contrib-compass');
    grunt.loadNpmTasks('grunt-contrib-watch');

    grunt.registerTask('default', ['compass']);
};

There are a couple of things I’d like to point out about the above. First, I added both Sass and JavaScript files to “watch” so I could show how to watch other kinds of files. This tutorial doesn’t cover Grunt modules that handle JavaScript files, but it would be useful to learn that next. Another thing is that I did not add “watch” to “grunt.registerTask,” because I don’t want to run “watch” as part of my default list of tasks. That is just a personal preference, though. If you want “watch” in the default task, I would take out any tasks that are being handled by “watch.”

Now go back to the terminal:

grunt watch

Grunt Watch with Compass
[note: the screen shot shows "*.sass" files being watched, but my code examples are dealing with .scss files... this was a typo I made while taking the captures]

Great, now Grunt has taken over your Compass stuff. By itself, this is kind of useless, but your next step is to learn more about what kinds of tasks you can run using Grunt and add them to your project. Such tasks include concatenating files, optimizing images, linting CSS and JavaScript, etc.

Grunt Watch in Action

Bonus: Adding LiveReload to Grunt

iveReload is a browser extention that automatically refreshes your browser after you make changes to the stylesheet. I recommend using it with Chrome for the best results, so go get the Chrome LiveReload extension.

If you are using Linux, there’s an extra step here. Upon clicking on the LiveReload icon to turn on the extension in Chromium, it will tell you to install “guard-livereload” to use it.

Should you need guard-livereload, type this into your terminal:

gem install guard-livereload

Type “gem list” after that and make sure both “guard” and “guard-livereload” are installed. Now navigate to your home directory (cd ~ in the terminal works) and create a file named “Guardfile” (no extension) with the following code in it:

guard 'livereload' do
   watch(%r.+\.(css?)$})
end

Personally, I have not had this working with anything but Compass projects so far, but in theory you should be able to add JavaScript and HTML files, etc., to the list of files Guard should watch. That is more in the domain of Ruby projects, so if you’re a Ruby nerd reading this tutorial and know a better way to get this working, please drop me a line.

Now, users of both Mac and Linux platforms (sorry, Windows… maybe you can use CygWin?) should be ready to add LiveReload to the “watch” task in Grunt.

Go back into Gruntfile.js and edit the “watch” configuration block so it looks like this:

watch: {
   scripts: {
      files: ['sass/*.scss', 'js/*.js'],
         tasks: ['compass'],
            options: {
               spawn: false
            },
    }
}

Run “grunt” in the terminal again. Make sure that Grunt says it is watching your Sass files and no errors were generated. Start the LiveReload extension in Chrome by clicking on the icon, then make some changes to your Sass code. You should see the browser refresh with the new styles showing. If not, be sure to check if there is an error in the terminal.

Foundation 5 Top Bar Breakpoint

Here’s a quick tip that’s sure to ease a couple of headaches: use your _settings.scss partial to change the Foundation 5 top bar breakpoint.

At first, I wasn’t sure how to go about this, because 1) I’m not too familiar with Foundation 5 and 2) I tried uncommenting a line in the _settings.scss file to override the preset, but doing so caused an error. A quick search online brought up a solution that won’t work for people using Sass.

This is a super-quick solution, and the cleanest.

Open your _settings.scss file and find the following lines:

// $topbar-breakpoint: #{upper-bound($medium-range)};
// $topbar-media-query: "only screen and (min-width: #{upper-bound($medium-range)})";

Uncomment those two lines. Let your Sass compile and see that you’re getting an error. The reason is that the lines setting the breakpoint variables are also commented out. Do a search on “Media Query Ranges” and uncomment all of the range variables you see below that line. Those are the breakpoints. Check for errors again… all clear!

You still don’t have a change in your top bar breakpoint. Pick one of the breakpoint variables you uncommented (I’m going for $large-range, which should fit a reasonably sized menu comfortably) and go back to the top bar settings:

$topbar-breakpoint: #{upper-bound($large-range)};
$topbar-media-query: "only screen and (min-width: #{upper-bound($large-range)})";

Save and take a look at the Sass compiler. There’s no errors, so go ahead and test the site out. Change the size of the browser a few times to see how the new top bar breakpoint settings are working. At this point, there’s still a problem. The mobile menu shows up to a very large screen size before switching to desktop mode. Why is that?

Both $topbar-breakpoint and $topbar-media-query are using “upper-bound” to get the highest value from the breakpoint variables they’re given. Looking back at the $large-range variable, it is actually an array with two values: 64.063em and 90em. That “upper-bound” is telling Foundation to use that 90em value as the breakpoint, but that’s much too wide. Let’s go back to the Foundation top bar settings and fix that:

$topbar-breakpoint: #{lower-bound($large-range)};
$topbar-media-query: "only screen and (min-width: #{lower-bound($large-range)})";

Save, let the Sass compile, and then check it out in your browser again. This time, the top bar will break out of mobile mode and into desktop mode at a reasonable 64em screen width. This gives you a Foundation 5 top bar that is in mobile menu on small tablets and shows its desktop mode on an iPad in landscape orientation (i.e., a screen width of 1024 pixels).

Read more about Foundation 5 top bar settings in the official documentation.

Using Susy Breakpoints

Susy is my favorite grid system, and it’s been that way since I started using Sass (and Compass). My two favorite points on Susy are these:

  1. It’s a grid, period. Not a framework, not a “one tool to rule them all.” It’s a grid.
  2. Susy allows developers to write well-formed, semantic HTML that isn’t cluttered with “span-10″ and “push-2″ classes. On large sites with complex layouts, it is really nice to have HTML you can just read and be able to see the document’s structure right away.
  3. Responsive development is pretty easy with this grid

One stumbling block I had in the beginning was figuring out how to use Susy breakpoints. This is actually super easy to do.

First of all, you’ll want to install Susy. I’m assuming that you have Compass, and therefore also Ruby, installed. If not, take a look at the RVM installation guide and the Compass documentation. Another assumption is that you’re on a Mac or Linux machine. If not, I hear Cygwin is a nice tool to use.

Now open your terminal and enter the command to install Susy as a Ruby gem:

gem install susy

Once it’s installed, make sure it works by entering:

gem list

If you see Susy in your list of Ruby gems, you’re good to go.

Now to start a new project, CD into the directory where you want to start your new Susy project and type this:

compass create your_project_name -r susy -u susy

In case you’re not yet familiar with how Compass works, the “your_project_name” will become the directory Compass creates to store your Sass and CSS files. I highly suggest also making this the directory where you will put the rest of your site files. Think of the entire site as part of the Compass project.

Now view the project directory in your editor of choice. Open up the _base.scss file in your Sass directory and take a look. Susy is already imported and has some presets. These presets assume you’re working on a desktop layout, or at the very least a desktop-first one. That’s not gonna work for us, so change it to match this:

$total-columns : 4;
$column-width : 4em;
$gutter-width : 1em;
$grid-padding : $gutter-width;

Going mobile-first, we’re starting out with four columns. This is fine for a narrow screen. Columns will be 4 ems wide, which isn’t going to change. The difference is that as the screen gets larger, we will add columns at our breakpoints.

Speaking of which, here’s the breakpoints I currently use:

$tablet : 52em 10;
$desktop : 68em 16;

These variables aren’t in the _base.scss file out of the box, so go ahead and add them. Technically, Susy does not even need these, and the naming convention is just one I decided to use. It’s better to set this up in one place now, though. As for the widths and column numbers, feel free to use the example I gave (they’re from a real project) or change them to suit your needs.

View your screen.scss file next. It’s importing _base.scss, so that’s all set. Susy also got you started with this:

.container {
@include container;
@include susy-grid-background;
}

This is the “container” class for your site. Its width is the sum of the widths of each column times the number of columns being shown, plus the column gutters and padding on each side of the grid. The “susy-grid-background” bit is nice, because it will display a light blue grid background wherever it is applied, making debugging a little easier. By the way, you can also rename that “container” class to something else.

To see the grid so far in action, create a web page inside your project directory and create a section or a div with the “container” class. Be sure to put some dummy text inside the element. Now open the page in your browser and take a look. You’ll see the grid in the background, but even on a large screen, there’s only four columns. Time to fix that.

Here is the syntax for a Susy breakpoint:

@include at-breakpoint(52em 10) {
// styles for this element at this breakpoint go in here
}

The above mixin “at-breakpoint” takes two variables as its arguments, first the width (I use ems, but any unit will work) and then the number of columns. Remember the “$tablet” and “$desktop” variables from before? Now’s the time to use them. The final product looks like this:

.container {
@include container;
@include susy-grid-background;

   @include at-breakpoint($tablet) {
@include container;
@include susy-grid-background;
}

   @include at-breakpoint($tablet) {
@include container;
@include susy-grid-background;
}
}

Open up your web page again and try decreasing and increasing the width of the browser. When a breakpoint is hit, the number of columns will change. Cool!

Just to make sure all this makes sense, though, let’s make a two-column layout. In your HTML, create two divs inside your container. Make the mobile layout first, where one div is stacked on the other:

.left {
@include span-columns(4);
}

.right {
@include span-columns(4);
}

This is a good starting point. Now introduce the tablet layout:

.left {
@include span-columns(4);

   @include at-breakpoint($tablet) {
@include span-columns(5);
}
}

.right {
@include span-columns(4);

   @include at-breakpoint($tablet) {
@include span-columns(5 omega);
}
}

The “.right” div gets an “omega” alongside the column number, since it’s the last column in its row. Notice how this is similar to how the container was set up? How to make the desktop layout should now be an easy guess. Go ahead and play with it.

Read more about how to work with Susy by reading the documentation at the official Susy website.

How to Remove Sass Cache From a Git Repo

On most projects, there are going to be some files you don’t need or want in its git repo, but you might not always think about them until they’re already in there. When the project involves Sass, the Sass cache directory is one of those things that aren’t really needed or wanted in the repo. No sweat, this is a fixable issue.

First things first, back up the directory:

cp .sass-cache .sass-cache2

Next, enter the following command:

git filter-branch -f --tree-filter 'rm -rf path/to/your/.sass-cache' HEAD

Now if you try to push to your remote like normal, you will probably get an error with something like this:

! [rejected]        master -> master (non-fast-forward)

This is because, as the error will explain, your remote repo now has files that your local repo is missing. You want to remove the .sass-cache from the remote, too, so force the push like this:

git push origin master --force

Make sure to change the branch name from “master” to the branch where you want to code pushed, of course. The important part here is just the “–force” flag.

When the push is sucessful, go ahead and take a look at the files in the remote branch where you pushed the code. The .sass-cache directory won’t be there. Nice! You’re a little closer to having a cleaner Git repo.

But you don’t want to do this again, right? If you don’t already have a .gitignore file, put one in the root directory of your local repo:

touch .gitignore
nano .gitignore

Replace “nano” with your preferred terminal text editor. Now add the following and save the file:

path/to/your/.sass-cache

Go ahead and check the status of your local repo:

git status

You won’t see Git telling you there’s .sass-cache files to add to staging. It ignored them, as we desired.

Yeoman: Getting it to Work on Ubuntu

In case you haven’t yet heard the buzz, Yeoman is one of the best front end development inventions since sliced bread. Think of it as having a jolly little British man living inside your command tool, awaiting your requests. Need to scaffold out an Angular project fast? He’s on it. Need to minify your style sheets and scripts? Already done. Want to download a good pint? Well, perhaps one day when the technology for teleportation is there…

 

Yeoman

Why Put Yeoman to the Job?

In recent months, I’ve been asked by my workplace to get cozy working with AngularJS, which is a great JavaScript framework if you haven’t already checked it out. When I cracked open my new book, though, it became apparent that a tool like Yeoman would be an immense, time-saving help. Why is that? There are numerous tools that can help make an Angular app rock solid, such as Jasmine and Karma Runner (both are JavaScript testing tools). Now you could spend time at the beginning of each project downloading all of the various files needed for each framework or plugin and assemble them by hand, but not only is that needlessly time-consuming, it’s also prone to human error.

It Doesn’t “Just Work”

At the office, I use a Mac, and it’s great. Installing Yeoman on that computer was a breeze (not counting the initial installation of tools needed just to use a Mac terminal for development in general… I use Homebrew).

The problem with installing Yeoman on Ubuntu is it’s not a Mac, but most online instructions are written for Mac users. Also, I use Oh My Zsh for my terminal, which depends on zsh, not bash. I went through a maddening labyrinth of permissions and zsh profile editing, along with many screw ups, before coming up with just the right set of steps to get Yeoman running on my Ubuntu 13.10 computer.

Headache #1 – Installing Node

Yeoman runs on Node to make use of its package manager tool, NPM. If you’ve worked with Ruby in the command line at all, using NPM to install packages is similar to installing gems. Like using Ruby to run Sass, you don’t need to know too much about Node to make use of Yeoman, but you do need to have it working.

Open up your terminal and enter the following commands to install your Node dependencies:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential openssl libssl-dev curl

Now that your dependencies are in order, install Node:

sudo apt-get install nodejs
sudo ln -s /usr/bin/nodejs /usr/bin/node
curl https://npmjs.org/install.sh | sudo sh

See that second line? On Ubuntu, there’s already a tool called “Node” that would otherwise cause a name conflict, so when Node installed on your system, it called itself something a little different, “NodeJS.” That’s all fine and good, but it can cause some issues later. The symlink created will make it as if your installation of Node were actually in the node directory. The third line installs NPM into your shell (the terminal).

Headache #2 – Installing Anything with NPM

At this point, if you try to install anything using NPM, you might see some big, nasty permissions errors… or nothing at all. When I first attempted to install Yeoman on my Ubuntu laptop, I got Yeoman installed, but issuing it commands got me nothing but the sound of crickets chirping.

Here’s the commands you can run in your terminal to prevent those errors:

echo prefix = ~/.node >> ~/.npmrc
echo 'export PATH=$HOME/.node/bin:$PATH' >> ~/.bashrc
. ~/.bashrc

Now if you’re a member of the zsh master race, change both instances of “~/.bashrc” to “~/.zshrc” so that you’re writing to the correct profile file.

Now Install Yo

Sorry, I kinda, sorta lied. Yeoman got a name change not to long ago, and it’s now going by just “Yo.” Now here’s the way to install Yo:

npm install -g yo

Easy peasy, lemon squeezy, right? Right.

Now that you have Yo installed, it’s time for a test flight. In your terminal, navigate into a directory where you’d like to start a new project. Now, just say:

yo

If everything went well, you should have a menu of options, including “Install a generator.” Select that one, and then at the prompt, type in something like “Angular” or “Ember,” or whatever sounds good to you (sorry, I tried “beer,” but there wasn’t any available yet). Choose one of the generators that pops up and wait for it to install.

Generators are Yo’s scaffolding tools. Think of them as blueprints for the foundations to your projects. Once he’s got one of these, your Yeoman has all the instructions necessary to lay down some ground work.

Now go ahead and select “Run the [name of your new generator here]” by selecting it at the prompt. If the generator starts pulling down some files and doesn’t issue you any errors, then you know that Yo is working just fine. Jolly good!

Getting More Help

The following links helped me figure out Yeoman installation, so maybe they’ll help you, too…