What’s so sassy about SCSS?

By Bill Searle — (Front-end Developer)

So you’ve been writing Cascading Style Sheets (CSS) and heard about SCSS? Well it was only a matter of time. If you’re comfortable with writing CSS then moving to a preprocessor like SCSS is a great step up.
If you’re just getting started with CSS, you should hold off SCSS and check out MDN’s getting started section.

What is SCSS?

Syntactically Awesome Stylesheets (SCSS). 
Did you notice the obvious mistake? 
There seems to be some confusion around Sass/SCSS and both options get used interdependently, but there is an important difference.

SCSS is the later version of the original Sass syntax and they don’t play together.

Check here for more info on the two syntaxes.

So what is SCSS? It’s Sassy CSS.

With that out of the way, lets start looking at some of the most commonly used features in SCSS.


Import

One of the problems with CSS is that it quickly becomes unwieldy, one file with hundreds or thousands of lines is hard to maintain.

SCSS helps break this down by building on top of the CSS import option.

Import allows you to literally import styles from another stylesheet file into your current file. So now we can break out our styles into seperate logical files.

It looks something like this:

// Folder structure
- css
main.css // this is all we have to serve in our app
- scss
main.scss
_header.scss
_typography.scss
_footer.scss

// inside main.scss
@import "typography"
@import "header"
@import "footer"

.scss file names prefixed with an underscore tell the compiler that these are partials and shouldn’t be compiled into their own .css file. We leave our main.scss file to import all the stylesheets we want and compile everything into one CSS file ready to serve on our website.


Variables

One of my favourite features of SCSS is the ability to define variables.

A variable is defined with the $ symbol and assigned a value.
Heres a sample of variables from a recent project:

// Colors
$c-yellow: #fff04b;
$c-yellow-dark: #ffe21d;
$c-yellow-light: #fbea82;
$c-yellow-lighter: #fef9d4;
$c-grey: #7b7b7b;
$c-grey-light: #c2c2c2;
$c-grey-lighter: #eaeaea;
$c-grey-lightest: #f7f7f7;
$c-grey-mid: #a7a7a7;
$c-black: #222222;
$c-white: #ffffff;
$c-error: #ff441d;
$c-beige: #d9d3c3;
$c-beige-50: rgba(#d9d3c3, 0.5);
// Fonts
$f-serif: 'Playfair Display', Georgia, Times, 'Times New Roman', serif;

// Example usage
h1 {
font-family: $f-serif;
color: $c-yellow-dark;
box-shadow: 0px 1px 1px 1px $c-grey-lighter;
}

If your client decides they don’t like that shade of yellow you’re using, it’s as simple as updating the variable value once which will filter down everywhere you’ve used it.
This is the fundamental use case for variables — change once.

Secondly it’s a lot easier to remember a name than all of those hex codes. The hardest part is deciding what to name your new variable! I prefix colours with “c-” and fonts with “f-” as my text editors autocomplete will list them out. Although the naming is completely up to you.

If there’s a chance your colours could change drastically, it doesn’t make sense when your $yellow variable has a red colour value. Something more generic like $brand-primary might work better.


Nesting

Nesting allows for better organisation of your styles and limits repetition. It works similarly to HTML’s nested hierarchy.

In the example below we have a parent element of <header> and two child <nav> elements — targeted with a class.

// SCSS
header {
.primary-nav {
ul {
background-color: #eee;
}
li {
list-style: none;
}
a {
color: blue;
}
}

.secondary-nav {
ul {
background-color: #ddd;
}
a {
color: green;
}
}
}
// Compiled CSS
header .primary-nav ul {
background-color: #eee;
}
header .primary-nav li {
list-style: none;
}
header .primary-nav a {
color: blue;
}
header .secondary-nav ul {
background-color: #ddd;
}
header .secondary-nav a {
color: green;
}

Notice how many times you have to write ‘header’ in SCSS compared to CSS and how you can contain your selectors?

When you start thinking of nesting selectors to match HTML markup you might be tempted to nest everything, but take a look at the example below and think about how this would scale.

// SCSS
header {
.primary-nav {
ul {
background-color: #eee;
li {
list-style: none;
a {
color: blue;
span {
font-size: small;
}
}
}
}
}

.secondary-nav {
ul {
background-color: #ccc;
li {
a {
color: green;
span {
font-size: small;
}
}
}
}
}
}
// Compiled CSS
header .primary-nav ul {
background-color: #eee;
}
header .primary-nav ul li {
list-style: none;
}
header .primary-nav ul li a {
color: blue;
}
header .primary-nav ul li a span {
font-size: small;
}
header .secondary-nav ul {
background-color: #ccc;
}
header .secondary-nav ul li a {
color: green;
}
header .secondary-nav ul li a span {
font-size: small;
}

Our SCSS is actually becoming less readable, less maintainable and too rigid. The resulting CSS is also longer and over the course of a large project you’ll be growing out your css file size with unnecessary selectors.

Try limiting yourself to three nested levels as in the first example.


Mixins

Mixins are a really powerful part of SCSS. They allow you to define a reusable and configurable block of CSS.

They are defined with the mixin directive, named, optionally given any variable properties and then followed by CSS selectors. The include directive is used to call a mixin.
The example below has default values assigned to it’s variables, (although not nessesary) so it can be used in two ways:

// SCSS
@mixin background-opts($pos: center, $size: cover, $rep: no-repeat, $color: $c-beige ) {
background-position: $pos;
background-size: $size;
background-repeat: $rep;
background-color: $color;
}
// Default usage
div {
@include background-opts()
}
// Result
div {
background-position: center;
background-size: cover;
background-repeat: no-repeat;
background-color: #d9d3c3;
}
// Configured usage
div {
@include background-opts(top, contain, no-repeat, #ccc)
}
// Result
div {
background-position: top;
background-size: contain;
background-repeat: no-repeat;
background-color: #ccc;
}

Operators

With SCSS we can do some maths SCSS has all the standard operators you need.

Here we’re just doubling the height of our nav variable for a larger screen. Easy.

$mobile-nav-height: 50px;
nav {
height: $mobile-nav-height;
@media (min-width: 768px) {
height: $mobile-nav-height * 2;
}
}
// Complied CSS
nav {
height: 50px;
}
@media (min-width: 768px) {
nav {
height: 100px;
}
}

Summary

We’ve just scratched the surface with what SCSS can offer so here’s a few options to get you started.

  • Hop over to codepen.io and start playing around.
  • Use an application like Koala.
  • Run the Ruby gem with command line.
  • Use a build tool like Gulp.

Be sure to check out http://sass-lang.com/ for full documentation and http://thesassway.com/ for more Sass tips and tricks.