Optimize Your CSS Code With Sass

Photo by Alice Dietrich on Unsplash

When you work on a large project, you find that the style gets more and more difficult to maintain, and when a client asks for changing the style of a part of the project you worked on it a long, long time ago ☹️️, yeah this is my reaction too.

Sometimes you ask yourself do you need to repeat this CSS code each time or you forget about the color you worked with and you hoped that there is a way to create variables inside CSS and pass them each time rather than pass the color.

Yes, this is when Sass goes in.

What is Sass?

Sass is a CSS pre-processor that compiles to CSS, meaning that all CSS rules are valid sass rules.

Sass adds superpower to CSS through variables, nested rules, mixins, functions, and more feature we will see them together.

Photo by Paul Hanaoka on Unsplash

Before we discover sass, I want to mention the BEM naming convention.

BEM naming convention:

BEM is a methodology for creating reusable components.

You can think of BEM as a naming convention that ensures that all your team members work with the same code base.

BEM stands for Block Element Modifier.

Our code should be like block__element — modifier

Block: represents a whole component or standalone entity.

Element: it is a part of the block.

Modifier: change the appearance, behavior, or state of an element or a block.

Now let’s imagine that we want to create a card component with a header, a body, and a footer like this.

To respect the BEM naming convention, our HTML should look like this:

<div class="card">
<div class="card__header">
<h1>The card header</h1>
</div>
<div class="card__body">
<p>The card body</p>
</div>
<div class="card__footer">
<h1>The card footer</h1>
</div>
</div>

And the CSS :

.card{ //some style}
.card__header{ //some style}
.card__body{ //some style}
.card__footer{ //some style}

Now let’s imagine we need to create two different card headers: the first with the background color red and the second with the background color blue.

How to proceed, do you have any clue, 🤔?

.card{ //some style}
.card__header{ //some style}
.card__body{ //some style}
.card__footer{ //some style}
.card__header--red{ background-color: red;}
.card__header--blue{ background-color: blue;}

Your HTML should look like this:

....
<div class="card__header card__header--blue">....</div>

By this convention, you are sure that all your team members on the same page and your code is easy to maintain.

Sass Nesting :

One of my favorite sass features is nesting. This means that you can nest CSS selectors inside each other.

Let’s look at this HTML code :

<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>

Inside the HTML we have a <li> nested inside a <ul> with sass we can achieve the same thing :

ul{
// ul style
li{ // li style}
}

Let’s back to the card example and make it with sass nesting :

.card{ 
//some style
.card__header{
//some style
.card__header--red{ background-color: red;}
.card__header--blue{ background-color: blue;}
}
.card__body{ //some style}
.card__footer{ //some style}
}

Sass Variables:

Let’s imagine that we have two main colors for our website white and black and your client needs to update the design and change the black color to green 🤨.

You need to refer to all files to update the color 😨 yes you need to change each of your style files.

A better way is to use sass variables. To create a variable you need the $ then your variable name. And to use it is simple, just add the variable to a CSS attribute.

$primary-color: white;
$secondry-color: black;
body{
color: $secondry-color;
}

Note: you can use Sass variables to hold any data (colors, fonts, margin….) and not just for colors.

Sass Mixins :

We can think of mixin as a reusable set of CSS rules.

Let’s imagine that we want all three title classes that share the font-size & font-weight:

.green-title{
font-size: 25px;
font-weight: bold;
color: green;

}
.blue-title{
font-size: 25px;
font-weight: bold;
color: blue;

}
.red-title{
font-size: 25px;
font-weight: bold;
color: red;.

}

A better way is to create a mixin that holds the font-size & font-weight .

Mixin syntax :

@mixin name {
property: value;
...
}

And to use this mixin, we use the @include name.

Let’s try it :

@mixin title {
font-size: 25px;
font-weight: bold;

}
.green-title{
@include title;
color: green;

}
.blue-title{
@include title;
color: blue;
}
.red-title{
@include title;
color: red;

}

I said Sass compiles to CSS, for now on I will show both the Sass code and the result of its compilation to CSS:

.green-title{
font-size: 25px;
font-weight: bold;
color: green;

}
.blue-title{
font-size: 25px;
font-weight: bold;
color: blue;

}
.red-title{
font-size: 25px;
font-weight: bold;
color: red;.

}

After compilation, Sass copy the rules of the mixin and added them to our classes.

Cool, but can we make it even better?

Do you know we can add arguments to the mixin?

Photo by MIKHAIL VASILYEV on Unsplash
@mixin name($argument1,$argument2, ...) {
property: value;
property: $argument1;
property: $argument2;
...
}

Let’s try it :

@mixin title($color) {
font-size: 25px;
font-weight: bold;
color: $color;
}
.green-title{
@include title($color: green);
}
.blue-title{
@include title($color: blue);
}
.red-title{
@include title($color: red);
}

After the compilation to CSS:

.green-title{
font-size: 25px;
font-weight: bold;
color: green;

}
.blue-title{
font-size: 25px;
font-weight: bold;
color: blue;

}
.red-title{
font-size: 25px;
font-weight: bold;
color: red;

}

Note: you can set a default value to mixin arguments for example:

@mixin title($color: red) {
font-size: 25px;
font-weight: bold;
color: $color;
}
.green-title{
@include title($color: green);
}
.blue-title{
@include title($color: blue);
}
.red-title{
@include title;
}

Sass extends:

Some times when you work on a page you found some classes that have the same attributes for example :

.btn {
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;

}
.btn-primary {
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;
background-color: blue;

}
.btn-secondry{
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;
background-color: red;

}
Photo by Joshua Hoehne on Unsplash

We have a code duplication, all classes have the same attributes and the only difference is the background-color.

To fix this, we can add a Sass extend for inheritance:

.btn {
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;

}
.btn-primary {
@extend .btn
background-color: blue;

}
.btn-secondry {
@extend .btn
background-color: red;

}

After the compilation to CSS :

.btn, btn-primary, .btn-secondary {
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;

}
.btn-primary {
background-color: blue;
}
.btn-secondry {
background-color: red;
}

Now let’s imagine that we don’t need a btnclass, meaning inside our HTML we will not use it and only we will use btn-primary & btn-secondary classes.

In this case, we can’t use the btn class to extend from it. Because we don’t put useless classes inside our code.

How to do it then?

Photo by AbsolutVision on Unsplash

The solution is to use a placeholder selector.

To create a placeholder:

%placeholder-name {
property: value;
...
}

Let’s try it:

%btn {
border-radius: 30px;
border: 1px solid black;
font-size: large;
font-family: "Courier New", Courier, monospace;
color: #fff;

}
.btn-primary {
@extend %btn
background-color: blue;

}
.btn-secondry {
@extend %btn
background-color: red;

}

You are confused about when to use mixins and extends, don’t you,🥶?

Extends or Mixins?

I will give you a simple rule: use extend only if you express a relationship between selectors. Sass extends equivalent to extends of Object-oriented programming 😀.

Let’s think about our example the btn-primary extends btn that makes sense.

If you don’t have a relationship between selectors, don’t use extends.

In all other cases, use mixins.

Sass Functions :

Sass comes with a very handy set of functions. I will show some of them.

quote(hello) => "hello"
str-index(Hamdi, H) => 1
abs(-3)=> returns the absolute value of -3.

You can find more about built-in functions here.

Now let’s see how to create our own functions :

@function function_name() { }

For example :

@function sum($a,$b) { return $a+$b; }

Conclusion :

Sass makes your CSS code more productive, cleaner, and easy to maintain.

I hope you have a better understanding of Sass and its features.

Also, I hope you enjoy this article.

Resources :

You can find more details from the official documentation:

https://sass-lang.com/documentation/modules

If you enjoyed this article, please clap it up 👏 and share it so that others can find it! Follow me to get more of me 😄.

I'm Hamdi, a software engineer 👨‍💻, and writer 📝