Let's take some notes on SASS.
SASS (Syntactically Awesome Style Sheets) is a preprocessor scripting language that needs to be compiled into CSS in order to work, as the browser will not understand its syntax. As we read on Sass website, it's "CSS with superpowers. Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.".
Sass uses .sass and .scss extensions, but as these two have a slightly different syntax, I will be using the .scss one.
How to compile .scss into .css?
If you use Visual Studio Code then the easiest way is to install an extension Live Sass Compiler. Then we need to go to Settings of this extension and click on Edit in settings.json under Settings: Format and pick the best set of settings for you. Here are your options:
"liveSassCompile.settings.formats":[ // This is Default. { "format": "expanded", "extensionName": ".css", "savePath": null }, // You can add more { "format": "compressed", "extensionName": ".min.css", "savePath": "/dist/css" }, // More Complex { "format": "compressed", "extensionName": ".min.css", "savePath": "~/../css/" } ]
Another option is to use Node.js and Gulp. Install Node on your computer, then run npm init in the project folder. Next step is to install all the dependencies that we are going to need: gulp, gulp-sass, sass.
npm install gulp gulp-sass sass --save-dev
Then, in gulpfile.js file (which you need to create) write a function that will watch the .scss files and automatically compile them to .css file in a location of your choice.
function buildStyles() {
return src('folder/**/*.scss') .pipe(sass()) .pipe(dest('css')) //choose a folder name where gulp will save compiled styles }//function to watch our scss file to recompile whenever we make changes
function watchTask() {
watch(['folder/**/*.scss'], buildStyles) //we pass in an array of files to watch. Here - all .scss files in directory named folder } exports.default = series(buildStyles, watchTask)Then in terminal run gulp or npx gulp. Gulp will create a css folder where the compiled styles will be saved. It will run both functions in turns: buildStyles (compiling .scss into .css) and watchTask (watching on our .scss files for any changes).
Variables
We create variables by assigning a value to a name that begins with $. Then we can refer to that name instead of the value itself.
SASS
$clr-orange: rgb(250, 190, 141)
p {
color: $clr-orange
}
CSS
p {
color: rgb(250, 190, 141);
}
Maps
Maps are all about associating keys and values.
$colors: (
"orange": rgb(250, 190, 141),
"green": #96ff93,
);
Looping through a map
SASS
@each $key, $val in $colors {.text-#{$key} {
color: $val
};
.bg-#{$key} {
background-color: $val;
};
}
CSS
.text-orange { color: rgb(250, 190, 141); } .bg-orange { background-color: rgb(250, 190, 141); } .text-green { color: #96ff93; } .bg-green { background-color: #96ff93; }Now we will loop through each colour twice, mixing it with white and black to create classes with different shades of it.
SASS
@each $key, $val in $colors {//light variations
@for $i from 1 through 3 { .text-#{$key}-light-#{$i}{ color: mix(white, $val, $i * 10); }//dark variations
@for $i from 1 through 3 { .text-#{$key}-dark-#{$i}{ color: mix(black, $val, $i * 10); }}
CSS
.text-green-light-1 {
color: #a1ff9e; } .text-green-light-2 { color: #abffa9; } .text-green-light-3 { color: #b6ffb3; } .text-green-dark-1 { color: #87e684; } .text-green-dark-2 { color: #78cc76; } .text-green-dark-3 { color: #69b367; } .text-orange-light-1 { color: #fbc598; } .text-orange-light-2 { color: #fbcba4; } .text-orange-light-3 { color: #fcd2af; } .text-orange-dark-1 { color: #e1ab7f; } .text-orange-dark-2 { color: #c89871; } .text-orange-dark-3 { color: #af8563; }Note that $key and $val exist only inside the loop.
Nesting
SASS
.card { display: block; padding: 1rem; border: 1px solid black; .card-title { font-size: 2rem; } .card-body { font-size: 1rem; a { text-decoration: underline; } } }CSS
.card { display: block; padding: 1rem; border: 1px solid black; } .card .card-title { font-size: 2rem; } .card .card-body { font-size: 1rem; } .card .card-body a { text-decoration: underline; }Partials
Sass lets us create partial .scss files with smaller bits of styles that we can include in other .scss files. Partial's name file must be preceded with underscore.
Note that the order in which we include partials has significant meaning.
Our file:
_variables.scss
In index.scss file:
@import 'variables';
Math
While in CSS we can make calculations using calc(), in SASS we can completely omit it, but the operation must be of the same type.
width: 100vw - 10% 100vw - 10vw;
We can also use SASS built-in modules.
math.div($number1, $number2) returns the result of dividing $number1 by $number2.
At the top of a .scss file:
@use 'sass:math';
Then:
$border-radius: 20px;
.card {
border-radius: math.div($border-radius, 4); // 5px
}
math.percentage($number) converts a unitless $number (usually a decimal between 0 and 1) to a percentage.
@debug math.percentage(math.div(100px, 50px)); // 200%
math.random($limit: null) - if $limit is null, returns a random decimal number between 0 and 1.
@debug math.random(100px); // 42
@debug math.random(10000); // 5373
Conditionals
We can create a class if the given condition is true.
@if(condition) {
.class { color: black; }} @else {
.class { color: blue; } } }Mixins
Thanks to mixins we can group together certain properties and values that are identical for numerous elements, so that we can reuse those values without having to rewrite them for every single element.
Let's create a mixin.
@mixin button() {
padding: 1rem 1.5rem;
color: blue;
border: 2px solid blue;
}
SASS
button {
@include button()
font-size: 1.2rem;
background-color: white;
}
CSS
button {
padding: 1rem 1.5rem;
color: blue;
border: 2px solid blue;
font-size: 1.2rem;
background-color: white;
}
Inside the parentheses of a mixin we can set a value to a property that exists in all elements that include it, but has a different value.
@mixin button($bg-color) {
padding: 1rem 1.5rem;
color: blue;
border: 2px solid blue;
background-color: $bg-color;
}
SASS
button {
@include button(white)
font-size: 1.2rem;
}
CSS
button {
padding: 1rem 1.5rem;
color: blue;
border: 2px solid blue;
font-size: 1.2rem;
background-color: white;
}
We can also set up a default value for a property if it has not been declared.
@mixin button($bg-color: #fff) {
padding: 1rem 1.5rem;
color: blue;
border: 2px solid blue;
background-color: $bg-color;
}
Parent selectors
By using & as a nexted selector we can refer to the outer selector without the need to repeat its name. This way we can add a pseudo-class or a selector before the parent.
SASS
.button { border: 5px solid blue;&:hover {
border: 5px solid red; } }CSS
.button { border: 5px solid blue; } .button:hover { border: 5px solid red; }Media Queries
First let's create a map, where the keys will be screen sizes and properties their corresponding screen widths.
$breakpoints: (
"small": 480px,
"medium": 720px,
"large": 1080px
);
Now let's create a mixin for each of the breakpoints.
@mixin small {
@media (min-width: map-get($breakpoints, "small")) {
@content;
}
}
// @content is the collection of all the properties from elements where this mixin was used
@mixin medium {
@media (min-width: map-get($breakpoints, "medium")) {
@content;
}
}
@mixin large {
@media (min-width: map-get($breakpoints, "large")) {
@content;
}
}
Finally, let's see how to use them.
.button {
@include small {
color: red;
}
}
@extend
@extend is a way of copying a css rule and reusing it with other selectors. Unlike @mixin, we cannot pass arguments. There's also a difference in how @extend and @mixin are compiled into css - @extend will put both selector names together, separated with a comma.
We can use .selector-name or %selector-name.
SASS
%flex-layout {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
// using % (placeholder rule) removes the name of the class (.flex-layout) when compiled into css.
.navbar {
@extend %flex-layout;
background-color: yellow;
.container {
margin-inline: 5%;
@extend %flex-layout;
}
}
css
.navbar .container, .navbar {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
Purging unused css rules
This is how we can get rid of all the unused css rules with Gulp and significantly reduce our output .css file.
First let's install an npm package.
npm install gulp-purgecss --save-dev
Remember to require the dependency in your gulpfile.js.
const { src, dest, watch, series } = require ('gulp');
const sass = require('gulp-sass')(require('sass'))
const purgecss = require('gulp-purgecss')
function buildStyles() {
return src('folder/**/*.scss')
.pipe(sass())
.pipe(purgecss({ content: ['*.html']}))
.pipe(dest('css'))
}
function watchTask() {
watch(['folder/**/*.scss', '*.html'], buildStyles)
}
//we are adding all html files to our watchlist,
because otherwise when adding an unused class only to our .html file
will not cause the .scss file to change, therefore the purging will not run again,
as it would only be watching the .scss files for changes
exports.default = series(buildStyles, watchTask)
Comments (0)
Be the first to leave a comment