Introduction to Sass

Learning Goals

  • Understand that Sass has two syntaxes: SASS and SCSS
  • Understand and apply the basics of Sass to follow the principles of DRY and KISS
  • Speak to the pros and cons of using a CSS Preprocessor


  • CSS Preprocessor A tool that processes some CSS-like language and turns it into CSS

Intro to Sass

Sass stands for Syntactically Awesome StyleSheets. Sass allows you to add more advanced syntax - like variables and functions - to your stylesheets. It is a CSS preprocessor that converts SCSS (Sassy CSS) into vanilla CSS.

A pre-processor is a tool that will process your code and compile it to a new format that adheres to the requirements of your environment. Think babel - this compiles our fancy ES6 syntax back down to ES5 so that it can be supported in older browsers.


Sass was originally part of another preprocessor called Haml. It used no curly braces or semi-colons, and the syntax adhered to strict spacing and indentation rules. Like so:

With this version, variables were assigned using ! and CSS styles were defined with =. Pretty different from the CSS you’re used to using now. Developers liked the additional control we had over writing our stylesheets, but wanted a syntax more similar to vanilla CSS. This is where SCSS comes in.

Now, this version of Sass looks a little different. Let’s compare the same code written in Sass and SCSS syntax. Sass Codepen SCSS Codepen

You may see the Sass syntax in the wild, but we will focus on the newer SCSS syntax.


SCSS stands for Sassy CSS (…seriously). In May, 2010 SCSS was introduced with more recognizable syntax.


Take a look at the SCSS in this codepen. Write down any syntactical similarities and differences you notice between SCSS and the plain CSS you’re familiar with.

Even if you’ve never worked with SCSS before, this syntax is a little bit easier to understand since it is so much closer to the languages that we use every day. Variables look like jQuery variables, things are nested in these guys: {}, wrong indentation won’t break your code, and assignments happen using : just like in normal CSS.

Although both Sass and SCSS are both still viable languages to use, movement has shifted significantly toward SCSS for several reasons:

  1. All modern CSS is valid SCSS. That means that you can rename an entire .css file .scss and nothing will yell at you. This not the case for pure Sass with the .sass file extension.
  2. There are no strict rules about indentation. There are still best practices, and if your indentation is all over the place you’ll make your teachers cry, BUT through our tears, your stylesheet will still function properly.

Note: For our purposes here, be aware that we will be working strictly with the SCSS syntax when we are working with Sass.

Turn and Talk

  • What is the difference between the SASS and SCSS syntax?
  • How would you explain what a preprocessor is to a five year old?

Why would we use Sass?

CSS in large apps can get crazy. Making changes to these large apps is tedious and extremely error prone. Sass makes it easier to change colors, fonts, and other properties by keeping your code DRY. This is the one of the key principles of Sass - DO NOT REPEAT YOURSELF .

Some of the cool tricks include defining variables that can be peppered across multiple CSS files, nesting elements to visibly reflect the HTML element relationships, using math equations to adjust sizes and values, adjusting colors using more intuitive language like “darken” and “lighten”, and bundling groups of styles together to easily reference throughout your CSS…to name a few.


One of the most obvious and immediately useful features of Sass is the ability to define variables.

As developers we strive to write DRY, clean code, and storing values for CSS styles as variables contributes to that. This means we can make color changes in one place, and the change will be reflected anywhere that the variable is referenced.

Similar to JavaScript, variables can hold a variety of data types: numbers, colors, strings, booleans, lists (array like objects), and maps (data structures that are key/value pairs).

Variable Syntax

Variables are defined by a $ immediately preceding the name of the variable (like jQuery), and a colon separating the name of the variable from the value.

$favorite-text-color: lime;

They can then be used anywhere in your stylesheet in place of that style. If I wanted all of my paragraph tags to have this color, my selector would look like this:

p {
  color: $favorite-text-color;

It’s also nice to avoid typing long, specific styles more than once. Instead we can reference a semantically logical variable.

$frilly-font: "Fantasy", cursive;
$main-font: "Arial", "Helvetica", "Copperplate", sans-serif;

$button-slide-transition: width 2s, height 2s, background-color 2s, transform 2s;

.main-content {
  font-family: $main-font;
  button {
    transition: $button-slide-transition;

Note: As some of you may already know, CSS can now support variables without the use of a preprocessor. In fact, there are a lot of compelling arguments out there regarding the fact that native variables in CSS are more powerful and flexible than the variables that you get with Sass. However, it’s important to note that if you are only using a preprocesser like Sass for the variables, you’re not using it right. Here is a good articleto read more about the differences between CSS and Sass variables.


Nesting makes representing relationships between elements in HTML possible in CSS.

For example, if you were writing pure CSS and wanted to target an anchor tag that was within a navigation element that was within a particular header tag, you can wrap the elements inside of each other to show the same visual hierarchy that you are used to seeing in your HTML:

$main-text-dark: #000;
$dark-red: #FF0000;
$link-light: #fff;

header {
  color: $main-text-dark;
  nav {
    background-color: $dark-red;
    a { color: $link-light; }
CSS Output
header { color: #000; }
header nav { background-color: #ff0000; }
header nav a { color: white; }


Be aware that having too much nesting can be a problem - resulting in hard to maintain CSS that is overly specific. Try to avoid excessive levels of nesting unless absolutely necessary.

Nesting & Psuedo-Selectors

A common scenario, when nesting is a good option, is when dealing with psuedo selectors. This makes it very transparent which element’s behavior is being targeted on a particular action.

To target a parent element and apply a psuedo selector, use &:psuedo-selector, as in the following syntax:

a {
  &:hover { color: pink; }

It is common to use the parent selector for situations where a secondary class changes a style.

Turn and Code

Write SCSS for the following HTML using nesting & variables, following the following criteria:

  • Link text font family should be Arial, Tahoma, or sans-serif.
  • On hover, make the link text red, and the button text white.
  • On hover, make the button have a box shadow of some kind.
  • For practice, define all styles as variables.
  <nav class="nested-magic">
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
      <li><button type="button" name="button">Log In</button></li>

Let’s say that your client wants everything thats red to be teal. Pretend that your CSS file is huge. Isn’t it awesome that you only have to change the CSS in one tiny little place?

Partials and Importing

One of the main benefits of Sass is having the ability to split your codebase across several CSS files without impacting PERFORMANCE - which brings us to the use of @import with Sass.

You may remember the @import CSS at-rule that can be used to import style rules from other style sheets when you were working with CSS in Mod 1. However, it’s okay if you don’t - as the use of this at-rule is typically a code smell/bad practice since it blocks parallel downloads of CSS files (each time you use @import it creates another HTTP request).

In the world of Sass, the @import directive works differently - which is important to know. Although @import is still used to require/import other stylesheets into other files, Sass will simply combine imported sheets into one final CSS file that is served to the browser, making it so multiple HTTP requests aren’t made.

*Note: Adding an @import for the same file more than once will still cause performance issues.

2019 Update: SASS is starting to switch to @use instead of @import. This fixes some issues, and gives us new, exciting features. With @use, the files are only imported once by default, no matter how many times you add it with @use. We get namespaces that help us to know where our imports are coming from. Here is a helpful article with more information on the features @use brings.

Generally, your structure will have the following:

  • Partial files that have an underscore prefix
  • A main file where you will be importing these partial files
// _variables.scss

// Colors
$favorite-text-color: chartreuse;
$gray-link: #aaa;

// Fonts
$frilly-font: "Fantasy", cursive;
$main-font: "Arial", "Helvetica", "Copperplate", sans-serif;

// Transitions
$button-slide-transition: width 2s, height 2s, background-color 2s, transform 2s;
// index.scss
@import 'reset';
@import 'variables';

@import 'Header';
@import 'Button';
@import 'Author';
@import 'Story';
@import 'Stories';

// index.scss
@use 'reset' as *; // the star removes namespace
@use 'colors'; // namespace is automatically set as "colors"
@use 'layout' as l; // we can change our name space to be "l"


.button { color: colors.$dark };

.wrapper { display: l.$flex };

But what about media queries? There are a lot of different approaches that you can take. Here’s a good blog post that walks through setting up responsive mixins for each component.

Turn and Talk

  • How does @import work in Sass? How is it different from the @import at-rule used in CSS? How is @use different from Sass’ @import at-rule?
  • With your partner, find two different ways to set up your file structure with Sass


A mixin allows you to define a set of styles that you want to reuse throughout your codebase. It also gives you the option to pass in values that make your mixin more flexible.

To use:

  1. You name them with @mixin name(arguments) { style }.
  2. To include them you use @include name.
/ Example
@mixin rounded-corners($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;

.box { 
  @include rounded-corners(50px); 
CSS Output
.box {
  -webkit-border-radius: 50px;
  -moz-border-radius: 50px;
  -ms-border-radius: 50px;
  border-radius: 50px;

Note: Just like variables, common convention is to place your mixins in a partial file that is separate from other styles

Turn and Code

In a CodePen, build the following chunk of html and SASS using mixins

  1. Create a mixin called level-one-header that has a font size of 32px, a font weight of 800, and a font family of Helvetica.
  2. Create a second mixin called level-two-header that specifies a font size of 24px, a font weight of 300, and a font family of Arial.
  3. Create another mixin called body-copy that has a font size of 16px, a font weight of 100, and a font family of Times New Roman.
  4. Using these mixins, create a small chunk of html. The HTML should have the following:
    • One h1 element using the appropriate mixin.
    • Two divs, each with an h2 and a paragraph tag.
    • For the two h2 elements, one should have a class of “pink”, which should have pink font, and one with a class of “subheader” that is grey, underlined, and all caps.
    • Each of the paragraphs should have a max width of 980px, but the one associated with the subheader should also be in italics. Refactor this CSS into SCSS using a mixin that takes in the two colors you need in your gradient. Apply the mixin to a div to give it a background gradient.


Another way to keep your code reuseable and simple is to make use of the @extend feature of Sass. Extend allows you to inherit properties from other selectors. Think of as parent styles – short, green eyes, big feet. Their children and grandchildren have the same base styles but with new age flair and coolness of their own.

.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;

.success {
  @extend .message;
  border-color: green;

.error {
  @extend .message;
  border-color: red;

.warning {
  @extend .message;
  border-color: yellow;

Compiles to:

.message, .success, .error, .warning {
  border: 1px solid #cccccc;
  padding: 10px;
  color: #333;

.success {
  border-color: green;

.error {
  border-color: red;

.warning {
  border-color: yellow;

You may have noticed that @extend and @mixin can be seen as accomplishing the same thing in a different way since they are both geared towards reusing styles across your project. A common question developers have with Sass is when you should choose to use one over the other, and why.

Research and Talk

In pairs, take 5 minutes to read two articles around this debate. Come together to discuss what you found.


Sass offers built-in color functions that allow you to adjust defined color values with ease. Most of the color functions operate by manipulating a single color value - while others can be used to combine colors in different ways.

Color is one of the most powerful components available to us in art and design; yet, it is something that is often underutilized by many programmers. Chances are that you’ve defined most (if not all) of the colors in your project using the predefined color names from the browsers, hex codes, or RGBA. This is all well and good; however, it fails to give you the same control over your colors as when you use HSLA.

Defining Colors

Let’s take a second to go back over the different ways to define a color in CSS.


Stands For: Red, Green, Blue, Alpha(Opacity)
Syntax: rgba(0-255, 0-255, 0-255, 0-1) or rgba(0-100%, 0-100%, 0-100%, 0-1 )
Example: rgba(255, 0, 0, 1) or rgba(100%, 0, 0, 1) (red)

Each value takes either a integer from 0-255 or a percentage from 0-100% representing the saturation/intensity of red, blue and green respectively, and blends them together.

Hexadecimal Code

A form of RGB notation written as pairs of hexadecimal values.
Syntax: #rrggbb or #rgb.
Example: #f00 or #ff0000 (red)

ProTip: Shorthand comes from duplicating each character. So #f00 (red) expands into #ff0000, or #fb0 (yellow) expands to #ffbb00;)


Stands For: Hue, Saturation, Lightness, Alpha(Opacity)
Syntax: hsla(0-360, 0-100%, 0-100%, 0-1)
Example: hsla(0, 100%, 50%, 1) (red)

Hue: A value from 0 to 360 indicating the value of RGB on a color wheel.

Think of the letters RGB distributed equally clockwise around a circle. (R)ed is at 0 or 360, (G)reen is at 120, (B)lue is at 240.

Color Wheel

Saturation: A percentage of the grayscale from 0% (no color) to 100% (full color).

Lightness: A percentage of white value from 0% (completely dark) to 100% (completely light); Standard colors default to 50%.

Alpha: A decimal value indicating transparency from 0 (invisible) to 1 (completely opaque).

Using RGBA to try to adjust lightness or saturation can be impractical and frustrating. In order to do this, you would need to shift each of the color channels - which would likely change the original color (hue). This matters most when you are looking to make color variations (fading, gradients, etc) from the same color. Using HSLA is a lot more predictable than RGBA, as seen in this demo tool

Light is an important piece of the design puzzle when it comes to working with color - something that is true for all mediums of art and design, including the digital mediums we use as FE developers.


In groups of four, research your assigned built-in color function. Reference the descriptions below, the Sass documentation on color functions, and the examples you are given. Make sure to play around with the code in a codepen - are there differences in using hex, rgba, and hsla? Why is this function relevant?

  • complement()
  • mix()
  • lighten/darken()
  • desaturate/saturate()

Color Functions


Returns the complement (aka the color that is 180 degrees from the value on the color wheel). Identical function to adjust-hue(color, 180deg)

Take a peek at the Color Wheel again for clarity.

$color1: hsla(240, 100%, 50%, 1);
// complement(hsla(240, 100%, 50%, 1)); ==> hsla(60, 100%, 50%, 1);

.complement-background {
  background: complement($color1)

mix(color1, color2, weight)

Mixes two given colors based on the weight percentage provided.

$weight in this function is relative to the two defined colors. Closer to 100% gives more weight to $color1, closer to 0% gives more weight to $color2.

$color1: hsla(0, 100%, 50%, 1);
$color2: hsla(240, 100%, 50%, 1);
// mix(hsla(0, 100%, 50%, 1), hsla(240, 100%, 50%, 1), 75%);
// mix(hsla(0, 100%, 50%, 1), hsla(240, 100%, 50%, 1), 35%);

.redder-background {
  background: mix($color1, $color2, 75%);

.bluer-background {
  background: mix($color1, $color2, 35%);

lighten/darken(color, amount)

Takes a color and a percentage value, returning a color with a lightness increased or decreased by given amount.

$color1: hsla(240, 100%, 50%, 1);
// lighten(hsla(240, 100%, 50%, 1), 30%);
// darken(hsla(240, 100%, 50%, 1), 30%);

.lighter-background {
  background: lighten($color1, 30%);

.darker-background {
  background: darken($color1, 30%);

desaturate/saturate(color, amount)

Remember that saturation is a colors representation on a gray scale.

desaturate() Will reduce a color’s saturation by that percentage. saturate() Will increase a color’s saturation by that percentage.

$full-color: hsla(240, 100%, 50%, 1);
$duller-color: hsla(240, 50%, 50%, 1);
// saturate(hsla(240, 50%, 50%, 1), 10%);
// desaturate(hsla(240, 100%, 50%, 1), 80%);

.vibrant-background {
  background: saturate($duller-color, 30%);

.dull-background {
  background: desaturate($full-color, 80%);


We’ve talked about a lot of the strengths/advantages of using Sass without acknowledging that there are downsides. Given what you know, make a case for possible disadvantages of using Sass


Instructor Resources

Lesson Search Results

Showing top 10 results