You may have heard of CSS preprocessing and be wondering what all the buzz is about. You may even have heard of Sass or LESS.
In short, preprocessing your CSS allows you to write more concise stylesheets which are formatted nicely and require less repetitive techniques commonly found when writing CSS code. The result is more dynamic styling and ample amounts of time saved when developing websites or applications.
If you already write CSS, then you can easily learn to preprocess your CSS. Once you understand the scope of Sass, you’ll wonder why you didn’t switch sooner.
How is Sass different to CSS?
Sass looks similar to CSS but has its obvious differences once you dive in. There are two ways of writing Sass and it’s ultimately up to you which style you prefer. I use the indented and bracketed style (.scss) in my projects because I like to really visualize where a block ends and begins when a lot of code becomes nested. Once processed the Sass code compiles to traditional CSS automatically using a preprocessing engine.
There are many apps available which allow precompiling your Sass to be seamless and downright easy. To install, you can use the command line as long as you have Ruby installed on your machine. If you’re not comfortable with the command line there are other options (more on this below) and if this is over your head visit Sass-lang.com to learn how to do this in an easy step-by-step format. In the end, using any method be it command line or app, the Sass installation will watch your changes and automatically compile down to traditional CSS for you.
I highly recommend using apps such as Codekit, LiveReload, or Mixture which help you set up a Sass project on a Mac from scratch or if you’re a Windows user I recommend PrePros. Codekit, my choice of preprocessor, helps me by preprocessing my Sass as well as validating and minifying your code to allow your website to run quickly and effectively. (The ability to create Compass or Bourbon based projects within Codekit is also an awesome feature but is beyond the scope of this article.) After you get more comfortable with Sass be sure to check out how to use Compass and Bourbon in your Sass projects.
So what is Sass?
Sass stands for Syntactically Awesome Stylesheets and was created by Hampton Catlin. Sass introduces new concepts like variables, mixins, and nesting into the CSS code you already know and love. These concepts ultimately make your CSS awesome, easier to write and more dynamic. All of these features combined, speed up any designer’s or developer’s workflow.
What commonly confuses people is the alternative ways to write Sass. You will see other tutorials or explanations of Sass using the .SCSS or the .Sass extension for their Sass files. This is apparent because there are two ways of writing the code which produce the same output. The most common I’ve seen, and the method I currently use is the bracketed version known as .SCSS. Another method is the .Sass extension which relies more heavily on indentation rather than punctual elements and is white space dependent. With this syntax there’s no need for semi-colons or brackets as you see in CSS and the .SCSS syntax.
Check out the example below.
.CSS
#container { width:960px; margin:0 auto; } #container p { color: black; }
.SCSS
/* Same as CSS but has variables and nesting. */ $black: #000000; #container { width:960px; margin:0 auto; p { color :$black; } }
.Sass
/* Same as SCSS without semicolons, brackets, and more dependent on indentation. */ $black: #000000 #container width:960px margin: 0 auto p color:$black
Structure
Okay so now you’re probably wondering how to get Sass setup for your own projects. The process is pretty easy, especially if you use Codekit or a similar application to help you along the way.
A typical file structure of a Sass project looks like the outline below. This may look daunting but I promise that your workflow will improve once you wrap your head around how things work together. In the end all of your Sass gets compiled down to one CSS file which will be the file you include inside your working documents be it HTML, PHP, etc…
stylesheets/ | |-- modules/ # Common modules | |-- _all.scss # Global level styles | |-- _utility.scss # Basic utility styles | |-- _colors.scss # Global Colors | ... | |-- partials/ # Partials - use these to target specific styles and @import on _base.scss | |-- _base.scss # imports for all mixins + global project variables | |-- _buttons.scss # buttons | |-- _figures.scss # figures | |-- _grids.scss # grids | |-- _typography.scss # typography | |-- _reset.scss # reset | ... | |-- vendor/ # CSS or Sass from other projects | |-- _colorpicker.scss | |-- _jquery.ui.core.scss | ... | |-- main.scss # primary Sass file - where your main Sass code will likely be.
How you set your structure up ultimately depends on you. Start with a basic structure and fine tune to your own needs and workflow.
@Import
Sass extends the CSS @import rule to allow it to import Sass and SCSS files. All imported files are merged into a single outputted CSS file. In addition, any variables or mixins defined in imported files carry over into the main file which means you can virtually mix and match any file and be certain all of your styles will remain on a global level.
@import takes a filename to import. As a last resort Sass or SCSS files will be imported via the file name of your choosing. If there is no extension, Sass will try to find a file with that name and the .scss or .Sass extension and import it.
If you have a typical Sass project setup you’ll notice some @import rules within a base file. This simply allows you to have multiple files which sync effectively once they are compiled, for example:
@import "main.scss";
or:
@import "main"; @Partials
If you have a SCSS or Sass file that you want to import but not compile to CSS, you can add an underscore to the beginning of the filename, which is otherwise known as a Partial. As the code is compiling Sass will ignore partials when processing to CSS. For example, you might have _buttons.scss, no _buttons.css file would be created and you can then @import “buttons”;
Best practice is to create a partials directory and place all of your partial Sass files inside it. Doing this insures you won’t have any duplicate file names which Sass will not permit, for example, the partial _buttons.scss and the file buttons.scss can’t exist in the same directory. Using partials is a great way to stay organized at a global level. As long as you @import the file, the Sass you write is usable throughout the entire project. Typically inside partials I create mixins or variables to use throughout my project. I name them based on their contents and the elements they are styling.
Variables
Variables in CSS are a breakthrough in modern web development. With Sass you can create variables for things such as fonts, colors, sizes, margin, padding, etc… The list is endless. If you write JavaScript or PHP the concept is fairly similar in terms of defining variables and conventions.
So why use variables? Easy, variables allow you to use an element more than once, similar to a class in HTML or a variable in JavaScript. For example, say you define multiple divs with a specific background color. You can use the variable which is easier to remember instead of the traditional hex code or RGB calculation. Making a variable with an easy to remember name allows for less copy and pasting and a more productive workflow. The same concept applies whenever a variable can be implemented, and with Sass that is virtually anywhere, for example this .scss:
#container { /* Here we define our variables */ $basetextsize: 12px; $container-space: 10px; $red: #C0392B; /* Variables are applied */ font-size: $basetextsize; padding: $container-space; color : $red; }
will result in this .css file:
#container { font-size: 12px; padding: 10px; color: #C0392B; }
Operations and functions
The cool part about variables is that they are extremely similar to those used in scripting languages. Variables inside Sass can be used inside both operations and functions. The standard math operations (+, -, *, / and %) are supported for numbers. For colors there are functions built into Sass which target lightness, hue, saturation, and more.
Having this functionality makes your code more dynamic than ever. For example, If you wanted to change the overall link color of your site you could simply change the variable, re-compile, and your site will update dynamically throughout. Check out another example below for a reusable navigation list, this .scss:
nav { $nav-width: 900px; $nav-links: 5; $nav-color: #ce4dd6; width: $nav-width; li { float: left; width: $nav-width/$nav-links - 10px; background-color: lighten($nav-color, 20%); &:hover { background-color: lighten ($nav-color, 10%); } } }
will result in this .css:
nav { width: 900px; } nav li { float:left; width: 170px; background-color: #E5A0E9; } nav li:hover { background-color: #D976E0; }
Nesting
Nesting is a huge reason why I love Sass. You write fewer lines of code in the end and all of your code is easy to read due to the nested formatting. (The same concept of nesting is also found in LESS.)
There are two types of nesting:
Selector nesting
Selector nesting in Sass is similar to how you would nest HTML:
<div id="container"> <div class="main"> <h1>Main Content</h1> </div> <aside class="sidebar"> <h3>Sidebar Content</h3> </aside> </div>
The Sass version of nesting:
#container { .main { width:600px; h1 { color: $red; } } .sidebar { width: 300px; h3 { margin: 0; } } }
would result in the following CSS:
#container .main { width: 960px; } #container .main h1 { color: #C0392B; } #container .sidebar { width: 300px; } #container .sidebar h3 { margin: 0; }
Property nesting
The second type of nesting is property nesting. You can nest properties with the same prefix to better target elements which results in less lines of code, for example this:
#container { .main { font: weight: bold; size: 12px; .intro { font: size: 20px; } } }
would result in this CSS:
#container .main { font-weight:bold; font-size: 12px; } #container .main .intro { font-size:20px; }
Mixins
Of all of the Sass features Mixins have to be the most powerful. Mixins are similar to a variable but on steroids. You can define a complete style of an element and re-use those styles throughout your project.
Mixins are defined using the @mixin directive, which takes a block of styles you created before and applies it to the selector of your choice using the @include directive. Below is a common CSS pattern used for creating a horizontal navigation menu. Instead of writing the same code for every navigation instance, just use a mixin and later include it where necessary. This concept can be done for anything you use over and over such as buttons, typography, gradients, etc…
/* Here we define the styles */ @mixin navigate { list-style-type:none; padding:0; margin:0; overflow:hidden; > li { display:block; float:left; &:last-child{ margin-right:0px; } } }
And here we include the mixin with one line of code:
ul.navbar { @include navigate; }
which results in this compiled CSS:
ul.navbar { list-style-type: none; padding:0; margin:0; overflow: hidden; } ul.navbar li { display: block; float: left; } ul.navbar li:last-child { margin-right: 0px; }
You can even go as far as creating customizable mixins which use arguments to update dynamically. On top of that you can include mixins within other mixins or create functions using mixins and more. The power behind these is absolutely huge.
There are some popular pre-defined mixin collections in which I mentioned earlier called Compass and Bourbon. With a simple @import in your project you can have access to already generated mixins commonly used throughout the web. There are so many options that it’s hard to cover everything available but it is definitely fun to experiment and get your hands dirty developing custom animations or transitions with a few lines of code rather than a screen full. Mixins make cross browser development a breeze if you don’t feel like typing browser defined prefixes over and over inside your CSS.
For example, here we create a mixin with arguments allowing it to be customized.
@mixin my-border($color, $width) { border: { color: $color; width: $width; style: $dashed; } } p { @include my-border (blue, lin); }
which gives us this CSS when it’s compiled:
p { border-color: blue; border-width: lin; border-style: dashed; }
Summary
While Sass has a learning curve, I truly believe that once you understand the methods and syntax, you’ll never want to go back to writing standard CSS again.
Sass is extremely powerful and I have only covered the basics here. With traditional CSS, we’ve all encountered the copy and pasting or find and replacing tasks which waste so much time in the development stage of your project. Give Sass a try and discover how to build an effective workflow in your future projects.