RadDevon

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.