Introduction to Sass Part 2 Refactor our Sass project with Variables and Mixins.

Now, let's change this into sass while going through its benefits; I'm changing the editor to dual layout so you can compare the two codes and see the difference between them.

Let's get rid of the property values we're repeating. We can do it in various ways, so let's start with the obvious first choice, variables. First, we identify what values are being used constantly and what values could be potentially used more times in other layouts. Webapps and websites normally have a color palette defined, which is used through the layouts. This is a good practice, so we can assume that the colors we use are going to be used constantly. Other values that are being used more than once are the ones for text-shadow and font-family, so the values we're going to save in variables are these:


#813772
#062F4F
#B82601
helvetica, arial, sans-serif
.1rem .1rem 0 black
all .25s;

The variable indicator in Sass is $ and the value is defined using :. Now let's assign variable names for each value.


$plum: #813772;
$tarawera: #062F4F;
$milano_red: #B82601;
$wild_sand: #F5F5F5;
$default-font: helvetica, arial, sans-serif;
$text-shadow: .1rem .1rem 0 black;
$default-transition: all .25s;

We use name that color to assign semantic names to color variables, which is a good practice: not only will the name match the color and make sense, but semantic names are much easier to remember on projects with a large number of layouts. Wait, the darker version of the colors are missing! Don't worry: Sass contains some useful methods to address this, but first let's apply our variables to the style:


  $plum: #813772;
  $tarawera: #062F4F;
  $milano_red: #B82601;
  $wild_sand: #F5F5F5;
  $default-font: helvetica, arial, sans-serif;
  $text-shadow: .1rem .1rem 0 black;
  $default-transition: all .25s;


  .banner-wrapper {
    align-content: center;
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    background-color: $plum;
    height: 100vh;
    width: 100%;
  }

  .banner-wrapper > .buttons-container {
    align-items: center;
    display: flex;
    justify-content: center;
    width: 100%;
  }

  .main-title {
    color: white;
    font-family: $default-font;
    font-size: 3rem;
    font-weight: bold;
    margin-bottom: 1rem;
    text-align: center;
    text-shadow: $text-shadow;
    width: 100%;
  }

  .default-button {
    background-color: $wild_sand;
    border-radius: .5rem;
    color: darkgray;
    cursor: pointer;
    font-family: $default-font;
    font-size: 1.25rem;
    font-weight: bold;
    margin: 0 .5rem;
    width: 15rem;
    padding: .5rem;
    text-align: center;
    text-shadow: $text-shadow;
    transition: $default-transition;
  }

  .default-button:hover {
    background: gray;
    color: white;
  }

  .default-button.-main {
    background-color: $tarawera;
    color: white;
  }

  .default-button.-main:hover {
    background-color: #04243D;
  }

  .default-button.-danger {
    background-color: $milano_red;
    color: white;
  }

  .default-button.-danger:hover {
    background-color: #8c1d01;
  }

This is looking better now; we have our values saved in variables, so we just define it once and use it through the style files. It's also more readable and semantically correct. Remember the darker versions of the colors? We still haven't applied them, so let's do that now.


  .default-button.-main:hover {
    background-color: lighten($tarawera, 5%);
  }
  .default-button.-danger:hover {
    background-color: darken($milano_red, 5%);
  }

And just like that, we're done! Sass employs two very useful methods to get brighter colors using lighten or darker colors using darken. Instead of hunting down the next tone in the color palette, we just have to apply one of these two methods and that's it! The way it works is pretty straightforward too. It basically receives two parameters: the color and the percentage of dark/light we want to apply.

Ok, now we have our values saved in variables and ready for reuse, but we still have these classnames all over the place, especially the buttons; let's clean that up using ‘nesting’, another basic but key feature of Sass.

`scss .default-button { background-color: $wild_sand; border-radius: .5rem; color: darkgray; cursor: pointer; font-family: $default-font; font-size: 1.25rem; font-weight: bold; margin: 0 .5rem; width: 15rem; padding: .5rem; text-align: center; text-shadow: $text-shadow; transition: $default-transition; &:hover { background: gray; color: white; } &.-main, &.-danger { color: white; } &.-main { background-color: $tarawera; &:hover { background-color: lighten($tarawera, 5%); } } &.-danger { background-color: $milano_red; &:hover { background-color: darken($milano_red, 5%); } } } Now, this is a lot better. Any element inside the curly braces is automatically recognized as child element, and the & is a helper that represents the element we are styling. This means every time we use &, it will be replaced with the name of the element we are defining properties to; in this case it’s .default-button so something like &.-main is the same as .default-button.-main. This helper can be also used for events like hover, clicked, focus, etc — just like we're doing with the hover for each modifier. What can we do to have even cleaner code? If we look, both containers use flexbox, so we can take advantage of that. We can also use another awesome Sass feature, mixins. Mixins allow us to define reusable blocks of properties, so can we take the flexbox values we are repeating and transform them into a mixin, which results in: scss @mixin flex_center { align-content: center; align-items: center; display: flex; flex-wrap: wrap; justify-content: center; } And now we can use it like this: scss @mixin flex_center { align-content: center; align-items: center; display: flex; flex-wrap: wrap; justify-content: center; } .banner-wrapper, .buttons-container, .main-title { width: 100%; } .banner-wrapper, .buttons-container { @include flex_center(); } .banner-wrapper { background-color: $plum; height: 100vh; } .main-title, .default-button { font-family: $default-font; font-weight: bold; text-align: center; text-shadow: $text-shadow; } .main-title { color: white; font-size: 3rem; margin-bottom: 1rem; } This looks a lot better and is completely reusable. Using @include, we can use the mixins, but what if we want to use mixins from other files? A small number of style files aren’t too difficult to include in the head, but if the number gets too big, things can get chaotic. Don't worry; we can use @import in Sass, and organize our files in a more efficient way. Let's divide our code into separate files for each class and import them into our main style file. First, we create a new folder called Components, then we add a file for each style we want. It’s important to use _ in the name, which allows Sass to recognize these files as partials. Then, we create a file for variables and another for mixins. Now we have a folder structure like this: project/ |- components/ |- _your_component-a.scss |- _your_component-b.scss |- _component-c.scss |- _your_component-d.scss |- _normalize.scss |- _variables.scss |- _mixins.scss |- application.scss Great! Today we not only transformed our code into something a lot more organized, readable, and reusable, but we also did it really fast. ### Summary: Let’s stop here for today; we learned about nesting, variables, mixins, and how to organize our files using @import. We’ve just taken a small bite of sass so far; there's still a lot more to learn! In the next episode we’ll go through the heavy features that Sass offers like functions, loops, and directives. We’ll also cover deep and more complex mixins and, of course, how to combine all these things. See you in the next video!