The SASS Preprocessor

CSS Preprocessors

The SASS Preprocessor is exemplified in a github repository.
Click here to download or fork.

Boilerplates is one way towards achieving a responsive and elegant design, but this path will always include one essential flaw: it comes at the expense of your freedom. If what you really want is particular and unique control over your own designs, you will often find that boilerplates steel more than they give. Generally speaking, boilerplates are templates. And templates are rarely creative.

CSS preprocessing is an entirely other way to go. Instead of taking the hazzle to make the tedious and complicated CSS you need from scratch – why not just make a better version of CSS before you start?

A CSS preprocessor does just that. While there are many different preprocessors out there – such as Sass, SCSS, Less, Stylus and PostCSS – they are all based on a very similar principle. So for now, we will just explore a single one: SCSS, and this will get you going towards understanding the concept.

SCSS and SASS are very much alike, so in this post we will just treat them as one. SASS is furthermore among the most widely used CSS preprocessors, so getting to know preprocessing by this example, may be a good idea.

What is a CSS preprocessor?

A CSS preprocessor let’s you write smarter CSS with added functionality. Compare the two following style scripts.

Standard CSS:

.navigation {
  background-color: yellow;
  padding: 20px;
}
.navigation ul {
  list-style: none;
}
.navigation li {
  text-align: center;
  margin-top: 20px;
}

SCSS

.navigation {
  background-color: yellow;
  padding: 20px;
  ul {
    list-style: none;
  }
  li {
    text-align: center;
    margin-top: 20px;
  }
}

As it appears, SCSS allows nesting in CSS, an absolutely understandable – but missing – feature in stylesheets. Further down we will go through more essential features in SCSS, such as variables, functions and more -but first you will have to learn how to use a preprocessor in your setup.

When you work with a CSS preprocessor you write CSS in a different style as you can see in the example above. Unfortunately there are no browsers that understands this styling, if you put it in a standard .css file, it wouldn’t render. What you do instead then, is to write the extended CSS in another file – i.e. called styles.scss – and then your preprocessor transpiles the document into a standard .css file.

To transpile btw, means to compile “from source to source”.

Installing SASS with nodejs

SASS can both be installed as a standalone or as a node module. Since we often use node in my classes, I assume you have it installed (otherwise go get it at this website). Next, open your terminal and type:

npm install -g node-sass

This installs the nodejs SASS compiler globally on your machine. Next, fire up a HTML project and link to an empty stylesheet, i.e. styles.css. This file is not important when we use a preprocessor, so leave it blank or don’t even create it – it will be produced be the preprocessor in a short while.

Now make a new file with the scss extension, i.e. styles. scss. Put the following sample into the file, or find something that suits you in the ref.

$font-family: 'Arial', Courier, monospace;
$font-size: 16px;
$padding: 20px;
$main-bgcolor : orangered;
div {
    font-family: $font-family;
	font-size:$font-size;
  	background-color: $main-bgcolor;
  p{
    padding:$padding;
  }
}

Now we just need to get the transpiler going, so we can see the resulting css. Open your terminal in the corresponding folder, and type:

node-sass styles.scss styles.css

If all goes well, you will now see that styles.css contains the preprocessed styling, and you webpage is ready to be styled with more SASS.

Basic SASS syntax & concepts

Variables

Variables are very handy to have in CSS – just like when you are programming, you can start off a project by declaring your most standard assets:

$main-bg-color: coral;
$main-colored-text: lightskyblue;

#div1 {
  background-color: $main-bg-color;
}
p.colored{
  background-color: $main-bg-color;
}

note: nowadays you actually can include variables in standard CSS as well. It’s a bit clunky but it works.

Nesting

One very thing about standard css, is the inability to nest selectors in a single statement. This you can do easily with SCSS:

.navigation {
  background-color: yellow;
  padding: 20px;
  ul {
    list-style: none;
  }
  li {
    text-align: center;
    margin-top: 20px;
  }
}

The above css only corresponds to the <ul> and <li> elements within a <navigation> element.

Mixin function

The mixin function allows you to collect a “bundle” or styling “object” that can be reused in statements. Prefix the function @mixin and follow by parenthesis ():

@mixin absCenterPosition() {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.box {
  background-color: red;
  width: 100%;
  height: 100vh;
  position: relative;
  
  div {
    width: 200px;
    height: 200px;
    background-color: blue;
    @include absCenterPosition;
  }
}

You can even pass parameters to the mixin function:

@mixin box-shadow($x, $y, $blur, $spread) {
  -webkit-box-shadow: $x $y $blur $spread;
  -moz-box-shadow: $x $y $blur $spread;
  -ms-box-shadow: $x $y $blur $spread;
  box-shadow: $x $y $blur $spread;
}
div {
    @include box-shadow(0, 5px, 5px, rgba(0, 0, 0, 0.7));
}

Functions

Functions in Sass are similar to functions in JavaScript. Just like JavaScript, functions in Sass can accept arguments and return some value. This makes sense for many purposes in CSS. Say you have a scenario where you need to do some math, in order to render som css property:

@function divide($a, $b) {
  @return $a / $b;
}

div {
  margin: divide(60, 2) * 1px;
  height: 200px;
  width: 200px;
}

Partials and Import

Very often in large web building projects, you need to split up CSS in many different files, simply in order to be able to organize your own workflow. Partials in Sass are separate files containing Sass code that make code modular. Using partials, you can have separate Sass files for different components.

A partial name always starts with an underscore _. You use an @import directive to import partial into another Sass file. For example, you can import the _header.scss file into main.scss file:

// main.scss
@import 'header';
//When importing a partial, we can omit the underscore() and .scss file extension.

Unlike CSS imports, Sass imports don’t send another HTTP request for fetching the partial, because during compiling all the imports are placed in a single CSS file.

Inheritance/Extend

In Sass, you can extend CSS properties from one selector to another. For this, use the @extend directive.

Use placeholder classes which starts with a % – i.e %notifications. The advantage of using placeholder classes is that it only prints in compiled CSS when it is extended, and can help keep your compiled CSS neat and clean.

For example:

%panel {
  background-color: green;
  border: 2px solid darkcyan;
}
.small-panel {
  @extend %panel;
  width: 70px;
  height: 70px;
}
.big-panel {
  @extend %panel;
  width: 200px;
  height: 200px;
}

The Ampersand (&) operator

If you have to style without the & operator, do something like this:

.btn {
display: inline-block;
padding: 5px 8px;
}.btn--green {
background-color: green;
}.btn:hover {
background-color: transparent;
}

With the & operator you can do it like this:

.btn {
display: inline-block;
padding: 5px 8px; &--green {
background-color: green;
} &:hover {
background-color: transparent;
}
}

@if and @else

The @if and @else directives are similar to if and else statements in JavaScript. For example:

@mixin text-color($val) {
@if $val == error {
color: red;
}
@else if $val == warning {
color: yellow;
}
@else if $val == success {
color: green;
}
@else {
color: black
}
}.heading {
@include text-color(error);
}

Here, we are using a mixin text-color which accepts an argument $val. We can have a different color for the heading depending on the value passed to the mixin.

@for and @while

The @for and @while directives are similar to for and while loops in JavaScript. For example:

@for $i from 1 through 4{
.col-#{$i} {
width: 100% / $i;
}
}

We use #{} to use variables inside a selector name and other CSS functions. This will be compiled into following CSS.

.col-1 {
width: 100%;
}.col-2 {
width: 50%;
}.col-3 {
width: 33.33333%;
}.col-4 {
width: 25%;
}

We can also implement the above code using the @while directive. For example:

$i: 1;
@while $i < 5 {
.col-#{$i} {
width: 100% / $i;
}
$i: $i + 1;
}

This will be compiled into following CSS:

.col-1 {
width: 100%;
}.col-2 {
width: 50%;
}.col-3 {
width: 33.33333%;
}.col-4 {
width: 25%;
}

@each

@each let’s you iterate through list or map objects in a quite fancy way. Say we had a website where we have named icon classes by a convention: class=”icon-40px”, “icon-50px” and so on. Using @each, we can now create a list – and the use the following (admittedly funny) syntax, to style them respectively:

//Create a list of sizes
$sizes: 40px, 50px, 80px;

//Run through the classnames - append the size name - and set the property.
@each $size in $sizes {
  .icon-#{$size} {
    font-size: $size;
    height: $size;
    width: $size;
  }
}

We can take this even further by using a map object:

//Create a map of elements 
$cardMap: (
  "cardSmall": "40px",
  "cardMedium": "80px",
  "cardLarge": "1200px",
);
//Run through the classnames - append the size name - and set the property.
@each $cardKey, $cardVal in $cardMap {
  .#{$cardKey} {
    max-width: $cardVal;
  }
}

Leave a comment