Improve your code with CSS Preprocessors. Sass.

When we develop a website or a hybrid app, one of the first things we notice is that our code usually gets complex and messy very easily, as our design evolves. CSS, especially in its first versions, doesn’t provide us with the required tools to organize and reuse properties. CSS preprocessors will help us with that task. In this blog entry, we will talk about Sass and we will show some of its main features.

What is a CSS Preprocessor?

A CSS preprocessor is just a tool that will let us write our styles in a specific language and then, after a compilation stage, it will generate the CSS files with the equivalent styles written in CSS. This initial language, which will be different depending on the preprocessor chosen, usually has some utils to ease the reusability and modularization of our code.

In this way, the use of the preprocessor is transparent to the page, as we just write our code using the preprocessor language, but in our HTML code, we keep on linking the generated CSS files, as we used to do.

There exist many different preprocessors, though maybe the most known ones are Sass and Less. Both of them have similar features and, despite in this entry we will focus on Sass, Less (and probably many other preprocessors) are good options.

Sass

Sass is a CSS preprocessor written originally in Ruby, but currently, there are other implementations available, for instance, one in Javascript, as it is explained in the official page. There exist two syntaxis for Sass. We will focus just on the SCSS syntax (Sassy CSS), which we will use in .scss files.

SCSS is a language built over the CSS standard. That means that any SCSS file containing just CSS would compile without any issue. This hugely helps the transition from CSS to SASS of any existing application, as we would just have to compile the SCSS with the same contents and use the generated CSS files in the same way as we were doing.

How to Install Sass?

In this case, we will use the JavaScript distribution, as we usually have Node installed in our machines, so we can take advantage of npm. Simply this command will install the latest version available.

npm install -g sass

In order to compile all our .scc files to CSS, we can use the following command, in which we will place the path to the folder where all the SCSS files live and also the path to the folder where the same structure will be replicated with the generated CSS files.

sass path/to/scss/folder:/path/to/css/folder

Let’s see some of the main advantages of using Sass.

Better Organization

Sass let us nest some selectors inside others. For example, if we have in CSS some styles for the selector nav and others for nav .active we can just place .active inside the nav block (and add some styles to nav at the same time). It is easier to understand by checking the following example, in which we can see how the generated CSS would look like.

nav {
    font-size: 2em;

    .active {
        font-weight: bold;
    }
}
nav {
  font-size: 2em;
}
nav .active {
  font-weight: bold;
}

There is also another way of nesting our styles when we use > in the selector for searching an element directly under another one. For example, the selector nav > .active could be written like this:

nav {
    font-size: 2em;
    > active {
        font-weight: bold;
    }
}
nav {
  font-size: 2em;
}
nav > active {
  font-weight: bold;
}

Also, we can nest the use of a selector and the same selector that has an additional modifier. For example, we could place a:hover under a, because & has the special meaning of the selector of the current block.

a {
    cursor: pointer;
    &:hover {
        color: blue;
    }
}
a {
  cursor: pointer;
}
a:hover {
  color: blue;
}

When we talk about nesting elements, media queries are a particular case. Instead of wrapping the selectors with the media query, it is the media query the one that is wrapped with the selector. This change makes the CSS code more readable, so we can easily see how the applied properties change based on the restrictions set in the media query.

.card {
    width: 50%;
    @media only screen and (max-width: 768px) {
        width: 100%;
    }
}
.card {
  width: 50%;
}
@media only screen and (max-width: 768px) {
  .card {
    width: 100%;
  }
}

Lastly, we can group properties of the same “family” (as it happens for example in the margin, padding, font…) in which the properties share a common root. In this case, we add : after the root of the property, so that Sass can understand that we are nesting properties and not selectors.

p {
    font: {
        size: 2em;
        weight: bold;
    }
}
p {
  font-size: 2em;
  font-weight: bold;
}

So, by making use of nesting we can enforce that the team group the selectors and properties, having a code that is both more readable and organized.

Code Reuse

Probably, the features that will help us more in improving the maintainability of our code will be those that let us reuse some parts of it. Sass provides us with different elements for that, such as variables, mixins or inheritance.

Variables

In the same way as other languages do, a variable in Sass will just contain a value we will be able to use in other parts of our SCSS. The variable can contain any of the different values we would use in CSS: numbers, colors, dimensions… The variable name should start with $ and its use is as simple as in the following example.

$primary-color:black;
$base-font-size: 1em;

body {
    background-color: $primary-color;
    font-size: $base-font-size;
}

.card {
    color: $primary-color;
    background-color: invert($primary-color);
    font-size: $base-font-size * 1.2;
}
body {
  background-color: black;
  font-size: 1em;
}

.card {
  color: black;
  background-color: white;
  font-size: 1.2em;
}

If we pay attention to the example, we can see we have defined a couple of variables for the base font size and base color of our website, and based on them we build the rest of styles. In this way, if we modify the base color, then all the rest of styles will be updated accordingly. In the example, we can also see how we can make use of mathematical operators, even functions (in this case, invert, which calculates the inverse of a color). If we needed, we could even implement our own functions.

It is important to take into account that, besides CSS already lets us define variables, and even we can perform simple calculations, we need that the browser of the user is one of the ones which support these features. This problem does not happen in SCSS, as the compilation is done before deploying our web, so the generated CSS won’t include the variables or functions, so that will be transparent to the browser.

Mixins

A mixin is simply a group of properties that we can apply in different places of our SCSS. With that, we can centralize our logic and avoid code duplication across different selectors. Besides, mixins admit input parameters, so we can take advantage of them to build generic mixins and customize each style when we use them.

To define a mixin we just have to use the keyword @mixin, after which we place the name of the mixin ant the input parameters it has. When we want to apply the styles included in the mixin, we have to use @include with the appropriate parameters, as you can see in the example below.

@mixin custom-bar ($background-color, $font-color, $bar-height){
    background-color: $background-color;
    color: $font-color;
    height: $bar-height;
    width: 100%;
}

nav {
    @include custom-bar(black, white, 2em);
    margin-bottom: 1em;
}

footer {
    @include custom-bar(black, lightgray, 1.5em);
    font-size: 0.8em;
}
nav {
  background-color: black;
  color: white;
  height: 2em;
  width: 100%;
  margin-bottom: 1em;
}

footer {
  background-color: black;
  color: lightgray;
  height: 1.5em;
  width: 100%;
  font-size: 0.8em;
}

Inheritance

There is an alternative for the mixins for applying a group of properties to different selectors: inheritance. In the inheritance, we just define the properties we want to extend inside a block whose name starts with %, and in the selectors we want to have then we use the keyword @extend.

%custom-bar {
    background-color: black;
    color: white;
    height: 2em;
    width: 100%;
}

nav {
    @extend %custom-bar;
    margin-bottom: 1em;
}

footer {
    @extend %custom-bar;
    font-size: 0.8em;
}
footer, nav {
  background-color: black;
  color: white;
  height: 2em;
  width: 100%;
}

nav {
  margin-bottom: 1em;
}

footer {
  font-size: 0.8em;
}

If we compare the generated CSS of a mixin and the equivalent by using inheritance, we will see that the generated CSS code from inheritance tends to be more compact and less repetitive. However, in the inheritance, you cannot define your input parameters.

Modularization

As our design becomes more complex, we will be able to split our files into smaller ones and then add them where we need them. Simply, by using @import 'path-to-the-file.css', we will load all the information contained in that CSS, and it would be the same as pasting all its contents just at that point of the file.

This would help us not only with a better organization by a modularization of our styles, but also we can reuse the same module in different folders. One typical case of this is having a file with the base configuration of the website (colors, sizes…) and load it in the rest of files so the styles are base on them.

That was the case of the popular front-end framework Bootstrap. This product is written in Sass and has a variables files, which is used to configure key aspects of the design. Due to this, we can load the main CSS file of bootstrap in our SCSS file (after having downloaded the SCSS available in the source code), and override the variables before that importation to have a Bootstrap completely customized to our needs.

// Variable overrides
$body-bg: lightgray;
$body-color: brown;
$font-family-base: "Times New Roman", Times, serif;
$headings-line-height: 1.8;

// Import Bootstrap
@import "path-to-bootstrap-folder/scss/bootstrap";

Conclusions

We have seen how the use of CSS preprocessors can help us in organizing our code in a better way. As it is less duplicated, we will follow better the DRY principle(Don’t Repeat Yourself), and in this way, we will be quicker both when writing the code for the first time and in future modifications. Despite this entry is focused on the use of Sass, we can obtain similar results with other tools. So we encourage you to use this one or any other so you can get all these advantages.

Leave a Comment

Responsable » Solidgear.
Finalidad » Gestionar los comentarios.
Legitimación » Tu consentimiento.
Destinatarios » Los datos que me facilitas estarán ubicados en los servidores SolidgearGroup dentro de la UE.
Derechos » Podrás ejercer tus derechos, entre otros, a acceder, rectificar, limitar y suprimir tus datos.

By completing the form you agree to the Privacy Policy

This site uses Akismet to reduce spam. Learn how your comment data is processed.