Refactoring with Sass & Compass – the CSS of your dreams
Having themed this blog in fleeting moments spread over a few months, the CSS was in need of a healthy dose of refactoring. I had been keen to try out Sass and Compass after having heard about them at WDCNZ, and this seemed like a perfect scenario.
Getting up and running
Installation was super easy :
gem install compass compass create [[project dir]]
(There are more detailed steps here if you’re sans-Ruby or still getting to grips with the command line.)
By default, compass auto-generates scss and corresponding css files for IE, print and screen. For this WordPress theme, I needed just a styles.css file in the root of the theme, so I removed the default files and tweaked the config.rb file to show Compass who’s boss:
http_path = "/" css_dir = "" sass_dir = "sass" images_dir = "images" javascripts_dir = "javascripts"
One of the best bits of Sass, or more specifically the scss syntax, is that a regular css file is already an scss file. So I moved my style.css file into the sass directory and renamed it to style.scss.
Next, I told compass to watch the sass directory, and compile my scss into css whenever it detects a change :
compass watch [[project dir]]
And Bob’s your uncle… a new CSS file. We’re up and running.
Refactoring
Up until this adventure with Sass, the CSS for this blog had been full of small experiments and fragments of long forgotten layouts. The finer points of the design were made up as I went along, and there was only ever time to work on it every now and then.
So the first thing I did was to organise the code a little better using partials and nesting.
Partials & Nesting
Partials allow you to break your scss file up in to numerous files. I created _tables.scss and _typography.scss – styles for data tables within an old post and the site-wide typography styles. Naming the file with an underscore tells Sass not to compile it into a css file, but just to import it as scss when requested, like so :
@import "typography"; @import "tables";
This is clearly a nicer way to organise groups of rules that are relatively independent. Have you ever worked on a seemingly endless CSS file that contained multi-line comments full of uppercase text trying to grab your attention and separate the different sections of the file? This fixes that.
And because Sass compiles these partials up in to the file they’re imported by, you only end up with one CSS file and your number of HTTP requests stays low. Double win.
Nesting helps you keep these individual files in even better shape and make your code an order of magnitude more readable. I went to town with these, starting with small tweaks to readability :
/** Before - CSS **/ th, td { padding: 6px; border-right: $tableBorder; } th:last-child, td:last-child { border-right: 0; }
/** After - SCSS **/ th, td { padding: 6px; border-right: $tableBorder; &:last-child { border-right: 0; } }
and then moving on to organising related styles together under one parent rule.
#latest-tweet { word-wrap:break-word; clear:both; p { &:BEFORE { content:open-quote; } &:AFTER { content:close-quote; } } a { text-decoration: none; &:hover { text-decoration: underline; } } }
Much nicer.
Using partials and nesting was a great help in refactoring the code to make it more organised and readable. These features are also invaluable at making it clear which old styles need removing and re-writing, and also making the process of doing this painless.
Just don’t take it to the extreme and break the Inception rule. You’ve been warned.
SassScript – variables and logic
Spending most of my days writing programming code rather than CSS, there were often moments when it seemed like variables, logic, math, conditionals or loops could make CSS less of a beast. Yet another thing that Sass has under control.
Variables helped reduce the repetition in the file too. DRY FTW :
$color1:#33c9f4; $color2:#37c7bd; $color3:#fccd0d; $color4:#ff8e10; $color5:#ef4b1a; $color6:#897f7e; $darkgrey:#444; $borderStyle:1px dotted #C9C9C9; $totalWidth:800px; $sidebarWidth:209px;
Next up was a for loop to help manage the color blocks. I already had some selectors which used the color variables, so I referenced these using the @extend directive. Here’s the before and after :
/** Before - CSS **/ .color-block .color:nth-child(5n+1) { @extend .color1; /** ... **/ } .color-block .color:nth-child(5n+2) { @extend .color2; /** ... **/ } .color-block .color:nth-child(5n+3) { @extend .color3; /** ... **/ } .color-block .color:nth-child(5n+4) { @extend .color4; /** ... **/ } .color-block .color:nth-child(5n+5) { @extend .color5; /** ... **/ } .color-block .color:nth-child(5n+6) { @extend .color6; /** ... **/ }
/** After - SCSS **/ @for $i from 1 through 6 { .color-block .color:nth-child(5n+#{$i}) { @extend .color#{$i}; /** ... **/ } }
Mixins
I experimented with mixins and other notable Sass features which seemed very useful. However in the case of this simple blog I found that refactoring my CSS even further meant these features were un-needed and that I could accomplish the same result with a more basic approach. Credit again to Sass for making this refactoring super easy and improving the clarity of what was previously a monster css file.
Tools
Every craftsman starts his or her journey with a basic set of good-quality tools.
Great book, wise words. Tools that I found useful for Sass development included:
-
Aptana
Sometimes seems to slow Eclipse to a crawl, but it comes with Sass code highlighting and includes a Terminal view, which is super handy when using Compass to compile your code. If you do this in a regular Terminal window behind Eclipse, you’ll miss any errors it throws, and wonder why your site hasn’t updated with your changes when you switch to your browser. With the Terminal view in Aptana, you can see the Compass output right below your code.
Also, the default colour theme uses a black background. This will make you look super-professional in front of your friends. -
CodeKit
This app lurks in the background watching you. When you update a file it will perform all sorts of pre-processing and compilation and then refresh the site in your browser. By the time you’ve switched to the browser, your code is already there. May only save you a second or two each time, but every little helps.
As well as Sass and Compass, it also includes support for Less, Coffeescript, minifying and error-checking Javascript, optimising images and more. -
css_parser
I like a good stat, and using compass stats on the command line gives me my fix. It shows the number of rules, properties and mixins for each sass file. Installing the css_parser gem (gem install css_parser) takes this a step further and shows you how many CSS rules and properties this is compiled in to.
-
Documentation
The Sass documentation is clear, comprehensive and also highlights relatively minor features, such as Sass comments vs. CSS comments.
Next steps
Now the building blocks are in place, my next steps will be to delve deeper into Compass and to use Sass variables and media queries to make implementing a responsive design even easier.