Did you ever wish you could get more out of CSS?! Maybe to be able to nest your selectors as opposed to rewriting them over and over. Or to have some functions that take care of the repetitive properties. Or maybe to just having the ability to set variables. Well, you can leverage that, and more, by using a CSS compiler, and in this tutorial, we’re going to talk about how to do this.

Introduction

SASS and LESS are two of the most popular preprocessor style sheet languages that can be compiled into CSS. They’re designed specifically to help you get the most out of your CSS writing experience. They introduce a lot of the basic functionality that you find in all high-level programming languages, things like functions, variables, loops, nesting, and more.

In this tutorial, we’re going to learn how to use and compile both SASS and LESS, and we’re also going to see the differences between the two.

Compiling SASS and LESS

There are quite a few ways of compiling SASS and LESS. We’re going to cover the main ones, but keep in mind that you should use one that ties together with your other actions. For example, if you’re already compiling or minifying JS in your project, you should use the same tool to compile SASS and LESS.

We need to talk about how to compile SASS and LESS before actually learning about them because we need a way to test what we learn.

The Importance of a File Watcher

Before we start discussing compilers, we need to understand what a file watcher and why it is important.

A file watcher scans the uncompiled files for changes and automatically compiles the code again and again. This process is important in development mode because it saves us from having to compile the source code manually, every time we make a change.

The SASS Tool

SASS’ official tool includes a file watcher out of the box, so if you only compile SASS in your project, it’s probably a good idea to use their own tool alone.

Installation

You can install it on any OS through NPM:

npm install -g sass

The -g flag will make the tool available anywhere in the system. It’s good if you will use the tool in multiple projects.

Here are some alternatives if you want to install it directly on your OS.

Usage

To compile a SASS file to CSS, you run:

sass style.scss style.css

That would compile the contents of the style.scss file and save the output to style.css.

Note: SASS supports two different syntaxes, SASS and SCSS. The difference is that SASS removes most of the special symbols that we find in CSS, like {, }, and ;. We’re going to talk about this a bit later, but for now, you just need to know that SASS compiles both .sass and .scss files, so if you see SCSS being used, know that it’s not a typo.

To watch for file changes on style.scss, we would use:

sass --watch style.scss style.css

Now, every time we change something inside style.scss, the tool will automatically compile the code and save it to style.css.

If we want to compile every .sass or .scss in a dir into another dir, we can do it with:

sass --watch src/sass:public/css

This will watch all the files in src/sass and compile them into public/css. It’s going to use their own file names, for example, style.scss will compile to style.css.

The LESS Tool

You can also install on any OS the LESS tool via NPM:

npm install -g less

Note that the LESS CLI tool is actually called lessc. If you run the command without any parameters, it will display the help screen.

Compiling files is similar to SASS:

lessc style.less style.css

However, the tool, compared to SASS, does not include a file watcher or a way to compile entire directories.

LESS in the browser

Even though the LESS CLI tool is not as good as the SASS tool, LESS makes up for this by providing a way of compiling LESS directly in the browser, at runtime. Now, even if this is production-ready, as it “just works”, this is not to be used in production environments, because it compiles the code on-the-fly, taking up processing power unnecessarily.

To make use of this, you need to do two things:

1. Include your LESS file as you would a CSS file, with the only mention that the rel="" attribute should have a value of stylesheet/less instead of stylesheet.


2. Load the compiler:

That’s it. The compiler will autorun itself and will compile all the files with rel="stylesheet/less" into in-page CSS and append it to the <head> element.

This option takes care both of compiling and watching, because every time you refresh the page, it recompiles the code.

This option is extremely useful if you’re working on small projects. Or even if you simply don’t have access to install a compiler and a watcher.

To see all the options supported by this technique, please see this page.

Other Compilers

When individual compilers aren’t a solution, we can use other compilers to do the same thing. We’ve talked in a previous article about Assets Compilation. Well, we could use any of the options listed there to compile SASS and LESS. Let’s see how we would do this using Laravel Mix.

Let’s start by opening a Terminal window and navigating to our project:

cd ~/tutorials/sass-less

Initiate NPM if you haven’t already done so previously.

npm init -y

Install Laravel Mix:

npm install laravel-mix --save-dev

Copy the configuration file:

cp -r node_modules/laravel-mix/setup/webpack.mix.js .

Copy the helper NPM scripts into package.json:

"scripts": {
  "dev": "NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch": "NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "hot": "NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
  "production": "NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

Create the necessary directories:

mkdir -p src/sass build/css

I’ve created a dir for SASS, but you can follow along if you use LESS too.

Create a SASS or LESS file, depending on which you want to use:

echo '' > src/sass/app.scss

Open the webpack.mix.js file and register the file to be compiled.

let mix = require('laravel-mix');
mix.sass('src/sass/app.scss', 'build/css');

For LESS, simply replace the .sass() function with .less().

And we’re done. We can now run the watcher:

npm run watch

And start writing SASS or LESS.

General Properties

These are features that both SASS and LESS support. They’re all going to be displayed in four versions, SCSS, SASS, LESS, and compiled CSS, but they all accomplish the same thing.

Variables

With the latest versions of CSS3, we can actually use variables within CSS itself, but that’s browser dependent at this point. Also, SASS and LESS offer more flexibility in defining variables. For example, we can use the basic math operators, +, -, *, and /.

This is how to define and use variables in SASS and LESS:

$font-family: Lato, Roboto, sans-serif
$primary-color: #4d56c5

body
  font: 16px $font-family

a
  color: $primary-color
$font-family: Lato, Roboto, sans-serif;
$primary-color: #4d56c5;

body {
  font: 16px $font-family;
}

a {
  color: $primary-color;
}
@font-family: Lato, Roboto, sans-serif;
@primary-color: #4d56c5;

body {
  font: 16px @font-family;
}

a {
  color: @primary-color;
}
body {
  font: 16px Lato, Roboto, sans-serif;
}

a {
  color: #4d56c5;
}

Nesting

One of the best features that both SASS and LESS provide is the ability to nest selectors. This means no more having to repeat the same selector over and over again, just to target other child elements.

Let’s see how this looks:

body
  font-family: Lato, Roboto, sans-serif

header
  background-color: purple

  .site-title
    font-size: 24px

    strong
      font-weight: bold

    i
      font-size: 32px
body {
  font-family: Lato, Roboto, sans-serif;
}

header {
  background-color: purple;

  .site-title {
    font-size: 24px;

    strong {
      font-weight: bold;
    }

    i {
      font-size: 32px;
    }
  }
}
body {
  font-family: Lato, Roboto, sans-serif;
}

header {
  background-color: purple;

  .site-title {
    font-size: 24px;

    strong {
      font-weight: bold;
    }

    i {
      font-size: 32px;
    }
  }
}
body {
  font-family: Lato, Roboto, sans-serif;
}

header {
  background-color: purple;
}

header .site-title {
  font-size: 24px;
}

header .site-title strong {
  font-weight: bold;
}

header .site-title i {
  font-size: 32px;
}

SASS and LESS are identical in this specific example.

Also, we can notice the biggest difference between SASS and SCSS here. SASS relies only on tabs or spaces to create the blocks of properties for a selector, as opposed to SCSS, which is more forgiving because it relies on { and }.

The Parent Selector (&)

This selector allows you to reference the parent selector inside a nested selector. Pay attention to the following example. & translates to the full selector of the parent.

#header
  h1
    &:hover
      background-color: lightgrey

    &.active
      color: red

    &, span
      display: block

    & + p
      margin-top: 0
#header {
  h1 {
    &:hover {
      background-color: lightgrey;
    }

    &.active {
      color: red;
    }

    &, span {
      display: block;
    }

    & + p {
      margin-top: 0;
    }
  }
}
#header {
  h1 {
    &:hover {
      background-color: lightgrey;
    }

    &.active {
      color: red;
    }

    &, span {
      display: block;
    }

    & + p {
      margin-top: 0;
    }
  }
}
#header h1:hover {
  background-color: lightgrey;
}

#header h1.active {
  color: red;
}

#header h1,
#header h1 span {
  display: block;
}

#header h1 + p {
  margin-top: 0;
}

Imports

You can import other files into the main file. This doesn’t create another request for a different file, but rather it embeds the file’s contents into the main file.

@import "header"
@import "content"
@import "footer"
@import "header";
@import "content";
@import "footer";
@import "header";
@import "content";
@import "footer";
header {
  background-color: purple;
}

section.content {
  background-color: #fff;
  padding: 30px;
}

footer {
  color: red;
}

You can import a file without specifying its extension name. Both SASS and LESS will try to guess it. However, if you want to import a CSS file that you don’t want to re-compile again, for example, a reset CSS file, you need to specify the extension. When importing .css files, the compiler simply copies the contents in and doesn’t touch the source.

Mixins

Both SASS and LESS support mixins, these act like functions. For example, this is how we’d create a mixin to avoid typing the same property 3 times with the same value.

=transition($property)
  -webkit-transition: $property
  -ms-transition: $property
  transition: $property

.box
  +transition(all .2s)
@mixin transition($property) {
  -webkit-transition: $property;
  -ms-transition: $property;
  transition: $property;
}

.box {
  @include transition(all .2s);
}
.transition(@property) {
  -webkit-transition: @property;
  -ms-transition: @property;
  transition: @property;
}

.box {
  .transition(all .2s);
}
.box {
  -webkit-transition: all 0.2s;
  -ms-transition: all 0.2s;
  transition: all 0.2s;
}

Operators

Both SASS and LESS allow +, -, *, /, and % as math operators. Here are a couple examples of how they can be used.

$padding: 15px

.container
  width: 100px + ($padding * 2)

.wrapper
  width: 1080px / 1920px * 100%

.thing
  width: $padding * 10
$padding: 15px;

.container {
  width: 100px + ($padding * 2);
}

.wrapper {
  width: 1080px / 1920px * 100%;
}

.thing {
  width: $padding * 10;
}
@padding: 15px;

.container {
  width: 100px + (@padding * 2);
}

.wrapper {
  width: 1080px / 1920px * 100%;
}

.thing {
  width: @padding * 10;
}
.container {
  width: 130px;
}

.wrapper {
  width: 56.25%;
}

.thing {
  width: 150px;
}

Comments

You can use // to leave line comments that will not be rendered in the final CSS. This doesn’t apply to /* ... */ which is a CSS feature. They will be left in place.

#header
  background-color: red // We're using red because we're too lazy to find a nicer color.
#header {
  background-color: red; // We're using red because we're too lazy to find a nicer color.
}
#header {
  background-color: red; // We're using red because we're too lazy to find a nicer color.
}
#header {
  background-color: red;
}

Exclusive Features

You can read all about the entire set of features of SASS, here, and about LESS, here.

Conclusion

Both of them are powerful extensions of CSS that will save you time in the long run. I encourage you to play more with them and read their extensive documentation that I’ve linked above. There’s a lot of great stuff in there.