What is Sass?

SASS is a scripting language that provides us with features and tools that regular CSS doesn’t have. Using Sass we can write more readable, maintainable and reusable code. A good way to look at it is as an extension that adds power and elegance to CSS. It gives us various features such as:

Variables

Nesting

Mixins

Functions

Partials & Imports

Inheritance (Extend functionality)

Control directives

In other words, Sass helps us organize large stylesheets in a more maintainable way. We’ll have a look into these features later in the article.

SCSS or Sass?

In Sass there are two ways of writing — SCSS and Sass— however after being compiled they generate similar output.

SCSS (aka Sassy CSS) is the modern standard. It’s syntax is very similar to CSS in that it uses brackets and semi-colons. Even normal CSS is valid in this syntax. The file extension is .scss .

. Sass is an older syntax that focuses on indentation to separate code blocks and newline characters to separate rules. It has the file extension .sass .

In this article, I will use SCSS as it’s the more natural syntax. It’s also really useful when converting regular CSS to SCSS, as you can just paste in the CSS and work from there!

Installing Sass

Before we can write Sass code it needs to be installed locally. We will now go through the process to setup the environment that will allow us to write then compile Sass.

Note: When Sass is compiled it is converted into regular CSS code that browsers can interpret and render.

Environment setup:

Before we start, you must have npm installed on your computer, it comes bundled with Node.js, you can install it from here. Go ahead and install if you haven’t already. If you are unsure whether you have Node.js installed or not, run node -v from your terminal. If you see a version number, it’s installed!

A note on terminal:

If you are new to Sass, chances are you may also be new to running commands from the terminal. It’s not as daunting as it might seem! And a real time-saver once you gain more experience. To open a terminal on a Windows PC right-click the Windows Icon and select ‘Windows Powershell’, if you’re on a Mac go to Finder > Applications > Utilities > Terminal.

Folder Structure:

Let’s create our project folders! They will be structured like so:

sass-project

|- sass

|- css

To create this structure, open terminal and change to the folder you wish to install our sass project into (via the cd command). Then run the following commands:

mkdir sass-project

cd sass-project

mkdir -p sass css

File Structure:

Of course you’ll need an index.html and main.scss. To create these files, run:

touch index.html

cd sass

touch main.scss

cd..

Note: Don’t forget to add <link rel=”stylesheet” href=”css/style.css”> to your index.html.

Initialize our Project Directory:

All projects that use npm need to be initialized. To do this enter the below command. This will create a package.json file for our project.

npm init -y

Install node-sass

node-sass is the library which allows us to compile .scss to .css. Run the following command to install node-sass as dev dependency.

npm install node-sass --save-dev

Compiling Sass Code to CSS

Next we need to create an npm script to run the compilation. Add this script inside the script section of our previously created package.json file.

"compile-sass": "node-sass sass/main.scss css/style.css"

We have here specified main.scss as our main Sass file, and style.css as the compiled CSS file.

It’s extremely handy to also add a --watch flag to your script. The watch flag tells the compiler to watch the source files for changes, and re-compile to CSS automatically each time you save your Sass files. Add --watch to the script and re-save:

"compile-sass": "node-sass sass/main.scss css/style.css --watch"

Now every time you save, the Sass will automatically compile to CSS — nice!

Note: Make sure you keep the terminal window running in the background – if you close the terminal the script will stop running. If you need to quit the process, you can press CTRL + C.

To compile our Sass code into CSS, all we need to do is run..

npm run compile-sass

Live Reload:

Why not add a live reload to our project. To do this run the following to install globally:

npm install live-server -g

Now make sure you’re still in the sass — project folder, and run:

live-server

And just like that, you’ve got a pretty neat dev environment with your project running locally on HTTP. You’ll need to keep live-server and npm run compile-sass running in two separate terminal windows.

We now have our project environment all set up! I encourage you to play around and experiment in this environment, with the features were about to take a look at below..

Sass Features

SASS effectively gives you a lot of the benefits of working with code but for stylesheets. Lets dive right in and take a look!

Variables

Variables are a way to store information that you want to reuse throughout your stylesheet. They allow us to store values for colors, fonts or really any CSS value that you want to reuse. We use the $ symbol to make something a variable. For example, in our SCSS we can define a color variable:

$color-primary: #ffff00; //yellow body {

background-color: $color-primary;

}

This will of course, set our background-color to yellow. Note you can use single line comments in Sass with // . When we then run our compile, it’ll output the following CSS:

body {

color: #ffff00;

}

This becomes extremely powerful when working on large projects. For example, if you wish to make a change to a colour used throughout your stylesheets. It’s much simpler to alter if it’s defined in one location as a single variable. The alternative is finding and changing over each value individually :-/

Nesting

When you observe the structure of an HTML file, you’ll notice it has a very clear hierarchy. CSS, on the other hand, lacks this visual structure. Which is why it has a tendency to become disorganized quite quickly. Enter Sass nesting! Using nesting, we can nest child selectors inside of the parent selector. This results in much cleaner and less repetitive code.

For example, take the following HTML:

<nav class="navbar">

<ul>

<li>Home</li>

<li>Store</li>

<li>Contact Us</li>

</ul>

</nav>

Using regular CSS, we would write this like so:

.navbar {

background-color: orangered;

padding: 1rem;

} .navbar ul {

list-style: none;

} .navbar li {

text-align: center;

margin: 1rem;

}

There’s a lot of repetition here. Each time we want to style a child of navbar , we have to repeat the class name. With Sass we can write much cleaner code. For example:

.navbar {

background-color: orangered;

padding: 1rem; ul {

list-style: none;

} li {

text-align: center;

margin: 1rem;

}

}

Notice the indentation. You’ll see the ul and li selectors are neatly nested inside the navbar selector.

Mixins

Another powerful feature of Sass are mixins. Using mixins you can group together multiple CSS declarations for reuse throughout your project.

Say we want to create a mixin to hold the vendor prefixes for a transform property. In Sass we’d code it like so:

@mixin transform {

-webkit-transform: rotate(180deg);

-ms-transform: rotate(180deg);

transform: rotate(180deg);

}

To add the mixin into our code we then use the @include directive, for example:

.navbar {

background-color: orangered;

padding: 1rem; ul {

list-style: none;

} li {

text-align: center;

margin: 1rem;

@include transform;

}

}

All the code in the transform mixin will now be applied to the li element. You can also pass values into your mixins to make then even more flexible. Instead of adding a specified value, add a name to represent the value like so:

@mixin transform($property) {

-webkit-transform: $property;

-ms-transform: $property;

transform: $property;

}

Now we can pass in whatever value we like whenever we call the mixin:

@include transform (rotate(20deg));

Functions

Much like JavaScript functions, Sass functions can receive arguments and return a value. For example:

@function divide($a, $b) {

@return $a / $b;

} div {

padding: divide(80, 2) * 3px;

height: 150px;

width: 150px;

}

At times doing math in your CSS can be useful. The standard math operators + , - , * , / , and % can all be utilized.

Partials & Import

Partials are a great way to modularize your CSS to help keep things maintainable. We divide up our Sass into separate files representing different components. A partial’s name always starts with an underscore _ .

We then import the partial using an @import directive.

Let's say our Sass file is getting rather large. We might make a partial that contains just the code that’s relevant to the header section, we’d call it _header.scss and move the appropriate code into that new file. We would then import it back into main.css like so:

// in main.scss

@import 'header';

Note: When you import a file there’s no need to include the _ or .scss file extension.

Inheritance / Extend

Another great feature of Sass is inheritance. We can extend CSS properties from one selector to another. For this, we use the @extend directive. See the following example:

.button {

background-color: #0000FF; // Blue

border: none;

color: white;

padding: 15px 32px;

text-align: center;

text-decoration: none;

display: inline-block;

font-size: 1.5rem;

}

This is pretty standard code for a CSS button. If say, throughout our document we have many different buttons, all of which are styled in a similar manner, we would have a good case for inheritance..

.button-secondary {

@extend .button;

background-color: #4CAF50; // Green

}

Our .button-secondary class will take on all of the properties and values set the .button class, with the exception of the background-color which we’ve decided to set to green. The use of inheritance really helps us to keep our code neat, clean and focused on constructing reusable components.

‘&’ Operator

This ampersand & operator is often used when nesting and it’s an extremely useful feature. Especially when coding with the BEM methodology. I’ve written previously about BEM here.

See the following HTML:

<button class="btn btn--red">Click me!</button>

Typical styling would be something like this:

.btn {

display: inline-block;

padding: 15px 32px;

} .btn--red {

background-color: #ff0000; // Red

} .btn:hover {

background-color: #fff; // White

}

With the & operator we can be much more efficient:

.btn {

display: inline-block;

padding: 5px 8px; &--red {

background-color: #ff0000; // Red

} &:hover {

background-color: #fff; // White

}

}

Notice that we’ve now nested the child selectors that use the same .btn name. When compiled the & operator will be replaced by its enclosing selector name.

Control Directives

Control directives and expressions are used in Sass to include styles only under defined conditions. As a feature, they’re quite advanced and are mainly useful in mixins. Common directives include @if , @else , @for and @while.

@if and @else

The @if and @else directives are similar to if and else statements in JavaScript. @if takes an expression and executes the styles contained within its block — if the evaluation is not false (or null). For example:

@mixin heading($size) {

@if $size == large {

font-size: 4rem;

}

@else if $size == medium{

font-size: 3rem;

}

@else if $size == small {

font-size: 2rem;

}

@else {

font-size: 1rem;

}

} .h1 {

@include heading(large);

} .h6 {

@include heading(small);

}

Here, we are using a mixin heading which accepts $size as an argument. We can have a different size for each of our headings depending on which value we pass to the mixin.

@for and @while

You can use the @for directive to execute a group of statements a specified number of times. It has two variations. The first uses the through keyword, it executes the statements from <start> to <end> , inclusive, for example:

@for $i from 1 through 5 {

.list-#{$i} {

width: 2px * $i;

}

}

This will produce the following CSS output:

.list-1 {

width: 2px;

}



.list-2 {

width: 4px;

}



.list-3 {

width: 6px;

}



.list-4 {

width: 8px;

}



.list-5 {

width: 10px;

}

If we replace the through keyword with to , it makes the loop exclusive. It will not execute when the variable is equal to <end> so..

@for $i from 1 to 5 {

.list-#{$i} {

width: 2px * $i;

}

}

Would yield the following CSS:

.list-1 {

width: 2px;

}



.list-2 {

width: 4px;

}



.list-3 {

width: 6px;

}



.list-4 {

width: 8px;

}

We can implement the above code using the @while directive. As its name implies, it’ll continue to output CSS produced by the statements while the condition returns true. The syntax is as follows: