CSS Preprocessors for the Timid
The modern web has so many technologies moving so quickly, itâs difficult to know where to start. Youâve probably heard of CSS preprocessors, the two most popular being LESS and SASS. They add convenience to CSS and make the syntax a bit more sane.
If youâre not yet confident with CSS, you may be tempted but ultimately unswayed by the promise of the preprocessors. Surely, I should have a firm grasp of CSS before I start branching out, right?
Preprocessor Syntax
Iâm here to tell you that the differences between CSS and LESS/SASS are small enough that you can pick up the preprocessors at any time â even when youâre first starting to learn â and start enjoying the convenience of these technologies right away. Letâs look at an example.
p {
color: #333;
font-size: 1.2em;
line-height: 1.2em;
}
p.aside {
color: #666;
font-size: 1em;
}
p code {
background: #ccc;
color: red;
font-family: 'Andale Mono', AndaleMono, monospace;
}
Here we have a few CSS styles for paragraph styling. On line 1, we style paragraph elements in general. On line 7, we apply some additional styling to paragraphs with the aside
 class. Lastly, on line 12, we apply styles to code
 elements inside p
 elements.
Letâs do the minimum we can to convert this into LESS and see how it looks.
p {
color: #333;
font-size: 1.2em;
line-height: 1.2em;
}
p.aside {
color: #666;
font-size: 1em;
}
p code {
background: #ccc;
color: red;
font-family: 'Andale Mono', AndaleMono, monospace;
}
Itâs exactly the same! Since LESS is a superset of CSS, regular CSS will work with LESS out of the box. The great thing about this is that you can write CSS into your LESS and gradually adopt some of the special features of LESS as you go along. Now, weâll once again do the minimum we can to convert this to SCSS, one of the two flavors of SASS.
p {
color: #333;
font-size: 1.2em;
line-height: 1.2em;
}
p.aside {
color: #666;
font-size: 1em;
}
p code {
background: #ccc;
color: red;
font-family: 'Andale Mono', AndaleMono, monospace;
}
Once again, we can take everything weâve learned about CSS and slap it into an SCSS file for the same result.
Just because we can use mere CSS as LESS or SCSS doesnât mean we should. Each of these preprocessors offers distinct advantages over vanilla CSS. Weâll get to that in a bit, but, first, Iâd like to show you this stylesheet minimally converted to original SASS.
This is going to be the biggest departure from the original CSS we have yet seen, but even the changes show here are trivial.
p
color: #333
font-size: 1.2em
line-height: 1.2em
p.aside
color: #666
font-size: 1em
p code
background: #ccc
color: red
font-family: "Andale Mono", AndaleMono, monospace
The difference here is in the syntax. If youâre a fan of Ruby or Python, youâll appreciate the omission of brackets and semi-colons. The code is much easier to read and just as explicit. Groupings are determined based on indentation. If youâre going to write good CSS, youâll want the indentations anyway. SASS goes one step further and lets the indentation take up the bracketsâ job of grouping your code. Otherwise, though, the code is identical to its CSS counterpart.
All this is great, but why would we want to write the same code with a different extension only to ultimately have to convert it back to CSS in the end for our browser? Â We wouldnât. Itâs great to have this safety net of vanilla CSS to fall back on, but these preprocessors can save a lot of time and work if you fully utilize them. Letâs look at some simple ways we can make this code better using a preprocessor.
Nesting
The single feature I used most is nested selectors. Letâs refactor that CSS into something a a bit nicer by avoiding some redundancy. Iâll demonstrate both SCSS and SASS. The LESS version would be identical to the SCSS for this example.
p {
color: #333;
font-size: 1.2em;
line-height: 1.2em;
&.aside {
color: #666;
font-size: 1em;
}
code {
background: #ccc;
color: red;
font-family: 'Andale Mono', AndaleMono, monospace;
}
}
When youâre doing any kind of coding, you want to remove repetition. Itâs a code smell that can lead to bigger problems down the line. CSS enforces this repetition. If you look back at the CSS version, we have to include the p
element in every selector or else the wrong elements may be selected.
SCSS allows us to, instead, nest selectors. In terms of this example, that means we provide the p
 selector one time. Then, other selectors that would have also used p
 are instead included within the p
 selectorâs brackets. Youâll notice the aside class has an ampersand in front of it. That means this selector only finds p
 elements that also have the aside
 class. Itâs equivalent to this selector in CSS: p.aside
.
The code
 selector does not include the ampersand. This is because it is a descendent selector. We are targeting any and all code
 elements that appear inside a p
 element.
I find itâs difficult to remember the rules when I think of them this way. Instead, I like to think in terms of the CSS I would write to achieve the same thing. If I have a space in my selector, that can be nested without any markings. I just make the nested selector include everything after the space. If the parts of the selector are butted against one another, I add an ampersand to the nested selector.
Hereâs the same example rendered in SASS.
p
color: #333
font-size: 1.2em
line-height: 1.2em
&.aside
color: #666
font-size: 1em
code
background: #ccc
color: red
font-family: "Andale Mono", AndaleMono, monospace
The only difference in this and the SCSS version is the lack of brackets and semi-colons.
Nesting makes it really easy to style pseudo-classes like :hover and :link. Letâs try this in SASS as it is my preferred style. Remember, if you want to adapt this to LESS or SCSS, just add semicolons after each property and brackets around every level of indentation.
a
&:link
color: red
text-decoration: none
&:hover
text-shadow: 1px 1px white
&:visited
color: maroon
The first selector here will be a:link in the final CSS, so we need an ampersand to denote there is no space between the components of the selector. Itâs so much more readable that the CSS alternative.
Variables
Letâs say you have a great color scheme for your web site. You want to be consistent, so you use these same colors in many different elements throughout your CSS.
body {
background: blue;
}
p {
color: red;
}
code {
background: rgba(gray, 0.7);
color: red;
}
hr {
color: red;
}
img {
border: 2px solid red;
}
This works great for a couple of months and everyone is happy. At that point, a customer contacts you to tell you she has trouble reading the red text on the blue background. You could just change the red, but you donât want to break the consistency of your color scheme. Instead, you decide to use a light blue as the main color, red as an accent color, and a black as the text color.
Youâll have to comb the entire stylesheet to look for the old colors and replace them with new. If you had variables, you could make three changes to alter the whole color scheme any time you want. Letâs rewrite these styles in SASS using variables.
$main-color: lightblue
$accent-color: red
$text-color: black
body
background: $main-color
p
color: $text-color
code
background: rgba(gray, 0.7)
color: $accent-color
hr
color: $accent-color
img
border: 2px solid $accent-color
In SASS and SCSS, variable names are prefaced with the dollar sign. In LESS, they are prefaced with the at symbol. Of course, both SCSS and LESS would also include CSS-style brackets and semicolons.
The SASS refactor of your styling is going to be much easier to maintain in the long run. You no longer have to find or remember all the locations where you used the accent color, the main color, or the text color. You only need to know that those are the colors you want to change. Change the variable values, and everything else falls into place.
Of course, variables can be used for more than just colors. You can put anything inside a variable. Then, just drop in the variable name wherever youâd like the value itâs been assigned.
Weâve only scratched the surface of what SASS and LESS can do to simplify your siteâs CSS, but, even with only these two simple features, the preprocessors make a good case for why you might want to leave CSS behind for your next project.
Feeding the Browser
Unfortunately, the browser doesnât care about your SASS/SCSS or LESS. It only has a taste for vanilla CSS. Maybe someday, browsers will evolve to be able to metabolize CSS preprocessors. Until then, we have to meet the browser on its terms.
We have a number of methods for getting CSS from our new styles. When I first experimented with LESS, I converted the LESS on the client side with JavaScript. This was a bad idea. It added about three seconds to my document load. Thatâs when I found CodeKit.
The idea is that you run CodeKit as youâre developing. It sits in the background and keeps things in order for your site. It will compile various languages into their browser-friendly counterparts and minify CSS and JavaScript to cut down on data transfered when someone hits your site. Itâs now an integral part of my workflow and churns my SASS into sweet CSS each time I save.
Update: 2022 Devon here. CodeKit is still a perfectly fine way to compile your LESS or SASS/SCSS to CSS. These days, though, I prefer command line tools because CodeKit is proprietary software, costs money, and runs on macOS only. Command line tools are free and cross-platform, which makes it easier to collaborate with other developers who may not use the same operating system as you or may not want to buy extra software just to work on your project. If you work for a company, itâs one less piece of software they need to license for each developer on your team.
A lot of modern front-end build systems can use plugins that will take care of compiling assets like LESS and SASS for you without any configuration. It makes onboarding developers a lot easier. Besides that, as CSS has added features like variables, the need for preprocessors isnât quite as clear today as it once was.