Getting Started with Sass
CSS pre-processors are very popular because they let you write CSS in a custom syntax to later be compiled to the vanilla CSS that our browsers require. Because of this compilation, the pre-processor can add a whole bunch of advanced features that help us write more efficient and modular styles with the peace of mind that in the end the browser will be able to support it.
For this tutorial, we will be using node-sass
to compile our Sass into CSS files.
Prerequisites
- Node and NPM installed. If you don't have them installed, follow our how to install Node guide.
Installing node-sass
Now let's get started. To install node-sass
, run this command:
BASHnpm install node-sass
Here is the confusing part, Sass has two syntaxes, one named Sass, and another named SCSS. For the purposes of the this tutorial, we will be working with the SCSS syntax. Feel free to learn about the differences between the two if you're curious.
With node-sass
installed, you should be able to run this command to get a CSS file from a SCSS file:
BASHnode-sass input.scss output.css
Alternatively, you can use the --watch
option to continuously watch a file or directory for changes and automatically compile if changes are detected:
BASHnode-sass input.scss output.css --watch
Variables
It wouldn't be a CSS pre-processor without variables. Variables in SCSS function pretty similarly to programming languages where they hold whatever data you want in them like a string or number.
Here's how variables look like in SCSS:
CSS$text-font: "Open Sans", sans-serif;
$success-green: #00a55e;
.heading {
font-family: $text-font;
background-color: $success-green;
border-radius: 0.25rem;
}
And here's the resulting CSS:
CSS.heading {
font-family: "Open Sans", sans-serif;
background-color: #00a55e;
border-radius: 0.25rem;
}
No surprises here, when you define a variable and then use it later on, the variable will be replaced by the value of the variable at compilation time.
Mixins
Mixins in SCSS are comparable to functions in programming. When you define a mixin, you can optionally have it accept parameters that you can use to build your styles. Let's look at an example:
CSS@mixin circle($size, $color) {
width: $size;
height: $size;
border-radius: 50%;
background-color: $color;
}
.small-green-circle {
@include circle(2rem, green);
}
.big-purple-circle {
@include circle(4rem, purple);
}
Which compiles to:
CSS.small-green-circle {
width: 2rem;
height: 2rem;
background-color: green;
}
.big-purple-circle {
width: 4rem;
height: 4rem;
background-color: purple;
}
Ever find yourself constantly using vendor prefixes? You can included them all in a single mixin so you don't need to keep repeating yourself, like so:
CSS@mixin transform($property) {
-webkit-transform: $property;
-ms-transform: $property;
-moz-transform: $property;
transform: $property;
}
.box {
@include transform(rotate(90deg));
}
CSS.box {
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
-moz-transform: rotate(90deg);
transform: rotate(90deg);
}
Pretty time-saving if you find yourself using these very often!
Extend
The extend feature in Sass exists for situations where you want inherit common styles but then add more styles.
Let's say you have styles around images but some you want to the left, and others to the right. Your styles could look something like this:
CSS.image {
box-shadow: 0 0.25rem 0.25rem 0 rgba(0, 0, 0, 0.25);
padding: 0.5rem;
}
.image--left {
@extend .image;
float: left;
}
.image--right {
@extend .image;
float: right;
}
This compiles to:
CSS.image, .image--left, .image--right {
box-shadow: 0 0.25rem 0.25rem 0 rgba(0, 0, 0, 0.25);
padding: 0.5rem;
}
.image--left {
float: left;
}
.image--right {
float: right;
}
Now in your HTML, you would only need to apply the classes image--left
or image--right
to get the full effect.
Nesting
As you might have noticed, CSS doesn't natively support nesting of styles. If you want styles to only apply when inside other styles, you must write something like this:
CSS.class1 .class2 {
color: red;
}
That is hard to maintain, especially as the codebase gets bigger. Sass offers much nicer syntax in that you can literally nest one inside another, like so:
CSS.class1 {
.class2 {
color: red;
}
}
Now you can visually see that the styles on class2
will only apply when it is nested inside an element with class1
as a class.
As expected, this compiles to this:
CSS.class1 .class2 {
color: red;
}
Ampersand Character
Alternatively, you can use the &
character, which in Sass refers to the parent selector, you rewrite the previous Sass but in reverse, like so:
CSS.class2 {
.class1 & {
color: red;
}
}
It might be confusing when you first see it, but if you replace the &
with the parent selector, you will see that we get the original styles back.
Here is a potentially more eye-opening example of using &
, imagine you have these button styles:
CSS.button {
&:visited {
color: red;
}
&:hover {
color: blue;
}
&:active {
color: green;
}
}
Look how easy it is to style a button's pseudo classes. You can just nest each class under .button
and add the styles you want inside.
It will be compiled to this:
CSS.button:visited {
color: red;
}
.button:hover {
color: blue;
}
.button:active {
color: green;
}
Operations
Because Sass already offers the use of variables, it is only natural that in addition to simply outputting the variables, that if you're working with numbers, that you can perform operations using them.
CSS$container-width: 40rem;
.container {
width: $container-width;
}
.container--half {
width: $container-width / 2;
}
.container--quarter {
width: $container-width / 4;
}
As expected, this compiles to:
CSS.container {
width: 40rem;
}
.container--half {
width: 20rem;
}
.container--quarter {
width: 10rem;
}
Functions
Sass offers built-in functions to do calculations and operations on your behalf. They range from color calculations, math-related ones like rounding and getting random numbers, and manipulating strings.
Let's look at one of their color-based ones, lighten
:
CSS$primary-color: red;
.darkened-red {
background-color: darken($primary-color, 30%);
}
This compiles to:
CSS.darkened-red {
background-color: #660000;
}
Conclusion
Sass is a very popular CSS pre-processor because of how powerful and flexible it is. It supports two different syntaxes so you can even pick your favorite. Learning a pre-processor is worth the time investment because it makes writing styles in general much faster and more efficient.
Resources
- Getting Started with Solid
- Create an RSS Reader in Node
- Git Tutorial: Learn how to use Version Control
- How to Set Up Cron Jobs in Linux
- How to deploy a .NET app using Docker
- How to deploy a Deno app using Docker
- How to Scrape the Web using Node.js and Puppeteer
- Build a Real-Time Chat App with Node, Express, and Socket.io
- Getting Started with Moment.js
- Setting Up Stylus CSS Preprocessor
- Getting Started with Vuex: Managing State in Vue
- How To Create a Modal Popup Box with CSS and JavaScript