I use Sass from the day I started to develop and cannot imagine my front-end coding without it. But the truth is I always knew only the top of what it is and what it allows to do.
First surprise is that original Sass syntax doesn’t use semicolons and curly braces:
$font-stack: Helvetica, sans-serif
body font: 100% $font-stack;
It is the other one which we get used to and which is called SCSS — Sassy CSS
— requires both curly braces and semicolons and allows to mix vanilla CSS with Sass in one file.
$font-stack: Helvetica, sans-serif;body { font: 100% $font-stack;}
Which gives us opportunity to start writing Sass by simply changing our old file extension from .css
to .scss
.
Another surprise is that variables have scope. If we define variable inside the rule it will be available only inside that rule without bloating the global scope.
And even more — if we are not sure variable has already been defined somewhere, we use !default
keyword in its declaration which says — if value exists in the outer scope then use it else please use this new value. Check the gist with comments below.
(All examples show SCSS in the first frame and resulted CSS in the second.)
Next feature is DRY principle support. Sass provides two ways to achieve it: extend
and mixin
.
I’m not sure if this holy war is still going but even after Sass introduced a great option of using extend with placeholder selector
which allowed to create rules without polluting global selectors namespace(well, now we pollute placeholder selector namespace):
mixins
for me still seems to be winning, because they cannot lead to generating huge CSS when we extend deep selector and they actually produce smaller gzipped files in comparison with styles which uses extend
(proof: https://tech.bellycard.com/blog/sass-mixins-vs-extends-the-data/).
So I will focus on mixins
in the following chapters as they have a lot of great features included.
null
as default parameter valueOK, mixin
takes some input parameters and puts the declarations defined in it wherever you say.
This gives us ability to put include
where we want instead of copy/pasting the same code many times and interesting thing about mixin
parameters are:
include
ing the mixin
null
— and this is really interesting case. This means that if we don’t specify the parameter and its default value is null then the whole declaration which uses this parameter as a value will be removed from generated CSS. This saves us time of writing if/else clauses or resetting the unintended declaration later and decreases the final file size 😌One more mixin
’s parameters feature is variable declaration
which behaves same as ES6 spread operator. It allows us instead of passing each parameter to mixin
individually just pass a list
or a map
(where map is similar to JS object) and values will be assigned automatically.
That’s how with this knowledge we can, for example, define dark and light themes:
Cool, right? Yes.
And another `cool, right` is that we can pass arguments through so that mixin
’s input become an input to its internal mixin
. This can be helpful if we want to extend a vendor utility, say Foundation’s ‘triangle’ mixin
to make it absolutely positioned:
ice Media Queries with Mixin @
contentSo mixins
give us great opportunity to pass declaration values(inline, block, #fffff, etc) or even property names(margin-right, color…) but what if we want to pass the whole SCSS block, not only parts of it? We can use content
keyword.
Let’s see how it can be done for a media query so the mixin
can be used later when we want to wrap our code with needed media query condition:
And what is cool here is that it actually allows me to stop searching for ‘media’ string in IDE each time I wanted to copy and past media query syntax into my code. I don’t need it anymore.
One important thing though to remember about content
is that the block of content passed to the mixin
is evaluated in the scope where block is defined, not in the scope of the mixin
.
So the variables we pass into themixin
as parameters cannot be used inside the content block:
Together with if
, for
and while
, we can use each
operator which can be quite useful for example when declaring icons:
Not super useful but good to know that Sass identifiers like mixin
or placeholder selector
names can use hyphens and underscores interchangeably. This means that dark-theme
and dark_theme
in Sass are the same. As well as these two guys:
༼ つ ◕_◕ ༽つ and ༼ つ ◕-◕ ༽つ
Well :) unfortunately we cannot verify the last two because they are invalid identifiers, sorry :)
Last thing I want to share is that the Sass official documentation is short.
Because CSS is not a programming language I underestimated power of tools involved in it. Later I spent only several hours going through Sass docs and nevertheless that gave me a whole bunch of insights on how to make code cleaner, more readable and performant.
Wish you fun coding ;)