An Overview Of SASS And SCSS

CSS is great in itself to design webpages. It involves a lot of recurring tasks and it’s difficult to manage the style sheets when the application is very huge. To avoid these recurring tasks and to write CSS in a better way, we need a preprocessor.

Preprocessors are CSS extensions. Preprocessors have all the features of CSS with additional features like variable, expression, mixin etc. A preprocessor will not do anything great in an end user's perspective but it can make development faster and easier. In the end user's perspective for performance, it can concatenate(import) all the style sheets to a single file so that all the styles for an application will be loaded in one network round-trip instead of separate requests for each style sheet.

Styles written using any preprocessor has to be converted to CSS and the compiled CSS file has to be included in the HTML page because the Browser understands CSS.

We have popular Preprocessors like LESS, SASS, Stylus. We are going to discuss Sass.

What is SASS

SASS is the acronym for Syntactically awesome style sheets. SASS was a part of another preprocessor called HAML. HAML was written by Ruby developers. Hence, SASS followed Ruby-like syntax & Ruby needs to be installed on your machine to compile SASS/SCSS files. In its third version, it got CSS like syntax and is referred as Sassy CSS or SCSS. Hence, this article is going to explain about preprocessors in general and SCSS.

Advantages

  • It makes your Application easy to maintain by avoiding all recurring tasks. Usage of additional features like variable, expression, nesting, inheritance, mixins, partials makes it more comfortable than CSS.

  • SASS provides many useful functions to manipulate colors and other values.

  • SASS provides advanced features like control directives for the libraries.

  • SASS allows to format and customize the compiled CSS file.

Pre-requisites

To use SASS, we need to install Ruby first. It’s a single click process. Make sure to check “Add Ruby executable to your PATH” option during installation. It makes Ruby available globally. However nowadays there are many editors including Visual studio 2013 Update 2 & advance that provides built-in support for SASS. Hence, if you can’t install Ruby also, there are other alternatives.

Gem will be installed with Ruby. Open command prompt with Ruby & install SASS with Gem by following command.

gem install sass

If any error occurs,

sudo gem install sass

For converting SCSS files to CSS file,

sass <sourcesassfilenamewithpath>.scss : <destinationcssfilenamewithpath>.css
sass sassfiles /style.scss : stylesheets/style.css

SASS vs SCSS

  • SCSS is the third version of SASS. They are just syntactically different from each other.

  • SASS

    ○ SASS code is compact, it needs fewer key strokes. We don’t need braces, semicolons.
    ○ Indentation plays a major role. Hence,  it forces coding standard.

  • SCSS(Sassy CSS)

    ○ More expressive
    ○ More readable
    ○ Easy to learn
    ○ Integration with css is easy. You can directly use the css code from Plugin. Css to SASS conversion tools are not 100% correct.
SassSCSS
★ // Variable
!primary-color= hotpink
★ // Mixin
=border-radius(!radius)
-webkit-border-radius= !radius
-moz-border-radius= !radius
border-radius= !radius
★ .my-element
//using variable
color= !primary-color
width= 100%
overflow= hidden
★ .my-other-element
// using mixin
+border-radius(5px)
★ // Variable
$primary-color: hotpink;
★ // Mixin
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
★ .my-element {
// using variable
color: $primary-color;
width: 100%;
overflow: hidden;
}
★ .my-other-element {
// using mixin
@include border-radius(5px);
}

SASS - SCSS conversion

SASS files can be converted to SCSS and vice versa.

  • Convert SASS to SCSS

    $ sass-convert style.sass style.scss

  • Convert SCSS to Sass

    $ sass-convert style.scss style.sass

SASS Script - Interactive shell

To launch the interactive shell, execute following command in command prompt opened with Ruby,

sass -i
>> 1px + 10px
11px
>> #777 + #777
#eeeeee
>> 10px/5px
2


SASS With Grunt

Grunt is a JavaScript runner that reduces our recurring task for deployment like concatenation or bundling, minifying css or js files etc.

Follow the steps to work with Grunt & SASS

  • Install NodeJS to get npm (Node Package Manager). Download NodeJS and install it.

  • Install grunt.

    If project and package.json file already exists, go to project root directory and execute the following command.

    npm install → It will install all the devDpendencies mentioned in package.json. 

    If project is created from scratch or does not have package.json file already.

    npm init → It will ask some questions and create package.json as per your responses.

    npm install grunt --save-dev → It will install grunt and add the same in devDependencies section of package.json file.

    npm install grunt-contrib-sass --save-dev → It will install grunt-contrib-sass.

    npm install grunt-contrib-watch --save-dev (optional)

  • Create Gruntfile.js in project root directory where we need to define tasks for Grunt task runner.

    Paste following in Gruntfile.js.
    1. module.exports = function(grunt) {  
    2. grunt.initConfig({  
    3. pkg: grunt.file.readJSON('package.json'),  
    4. sass: {  
    5. dist: {  
    6. files: {  
    7. // destination file : source file  
    8. 'style/style.css' : 'sass/style.scss'   
    9. }  
    10. }  
    11. }   
    12. });  
    13. grunt.loadNpmTasks('grunt-contrib-sass');  
    14. grunt.registerTask('default',['sass']); // Register default grunt task  
    15. }  
    Now in cmd, you can go to your project root directory and execute the following Grunt SASS,

    Or

    grunt

    It will compile the SCSS file and create css file for you.

Sass features

Variable $
Nesting {{}}
Inheritance @extend
Mixin @mixin @include
Expression $ function () +
Partial _ @import
Function 
Directive 

Variable ($)

Mostly used values can be kept in the variables. Let’s say, you want to give a particular color to some elements along with some other styles in your page. Say in the future, you want to change this color. If you are using css, you need to change this color value for all the elements separately. If you are keeping this color value in some variable and using it, you just need to change this variable value.

SCSS CSS
$cre-bs-font-color: hotpink;
.cre {
color: $cre-bs-font-color;
// some other styles
}
.bs{
color: $cre-bs-font-color;
// some other styles
}
.cre {
color: hotpink;
}

.bs {
color: hotpink;
}

Expression

SCSS allows to use arithmetic operators (+, -, *, /, %) for the expression, to provide calculated value for styles.

  1. SCSS doesn’t evaluate plain css. E.x. font: 15px/12px won’t evaluate as it indicates line height font color.

  2. Use a variable or parenthesis for expressions.
    1. Width: 100px/2 // This won’t evaluate, but followings will evaluate  
    2. $width: 100px; width: $width/2;  
    3. Width: (100px/2)  
  3. Parenthesis for list values doesn’t evaluate.
    1. font:(italic bold 10px/8px) // Won’t evaluate
  4. Use function, + for expression.
    1. margin-left: 5px + 8px/2px; // This will evaluate  
SCSS CSS
p {
font: 10px/8px;// Plain CSS, no division
$width: 1000px;
width: $width/2;// Uses a variable, does division
width: round(1.5)/2;// Uses a function, does division
height: (500px/2);// Uses parentheses, does division
// Uses +, does division
margin-left: 5px + 8px/2px;
// In a list, parentheses don't count
font: (italic bold 10px/8px); }
p {
font: 10px/8px;
width: 500px;
width: 1;
height: 250px;
margin-left: 9px;
font: italic bold 10px/8px;
}

Nesting {{}}

You can nest dom elements for styling in the way they appear in dom. It avoids repetition of parent selectors. It also makes Application maintainable. E.x., you want to add/remove/change a parent element.

SCSS CSS
.my-parent{
font-weight: bold;
background-color: #F00;
.my-child{
background-color: #0F0;
border: 1px solid black;
}
}
.my-parent {
font-weight: bold;
background-color: #F00;
}
.my-parent .my-child {
background-color: #0F0;
border: 1px solid black;
}

Nested Properties

Properties (like font, border, margin, background etc.) can also be nested to remove repetitive prefixes.

SCSS CSS
.funky {
font: {
family: fantasy;
size: 30em;
weight: bold;
}
}
.funky {
font-family: fantasy;
font-size: 30em;
font-weight: bold;
}

Parent Selector

The parent element can be selected with &. This is particularly helpful for pseudo classes.

SCSS CSS
#main {
color: black;
a {
font-weight: bold;
&:hover { color: red; }
}
}
#main {
color: black;
}
#main a {
font-weight: bold;
}
#main a:hover {
color: red;
}

Inheritance

Styles for a selector can be reused using inheritance by using @extend keyword. Again, it avoids repetitive work of writing the same style multiple times. You can just reuse already defined styles and add more to it.

SCSS CSS
.foo {color: black;
border: 1px solid black;
}
.bar {
@extend .foo;
background-color: red;
}
.foo, .bar {
color: black;
border: 1px solid black;
}

.bar {
background-color: red;
}

Multiple Inheritance/ Extend

It allows you to extend multiple styles also.

SCSS CSS
.error {
border: 1px #f00;
background-color: #fdd;
}
.attention {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
@extend .error, .attention;
border-width: 3px;
}
.error, .seriousError {
border: 1px #f00;
background-color: #fdd;
}
.attention, .seriousError {
font-size: 3em;
background-color: #ff0;
}
.seriousError {
border-width: 3px;
}

Multi-level Inheritance / Chaining Extends

Extends can be chained also.

SCSS CSS
.message {
padding: .5em;
}
.message-important {
@extend .message;
font-weight: bold;
}
.message-error {
@extend .message-important;
}
.message, .message-important, .message-error {
padding: .5em;
}

.message-important, .message-error {
font-weight: bold;
}

Mixin

Mixins are like functions in SCSS. It can take a style value, selector and other SCSS data types as well.

SCSS CSS
@mixin border-radius($radius) {
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
.my-other-element {
@include border-radius(5px);
}
.my-other-element {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}

Partial

  • It’s particularly helpful when you have a .scss file(say for variables, mixins, expressions) and you don’t want it to be converted to css. In fact, you want to use it in some other .scss file.

  • Filename should start with _. eg _sassPartial.scss

  • Then you need to import this partial SCSS file in your main SCSS file as shown:
    @import “sassPartial”.

  • It’s recommended to keep this import statement at the beginning of file. You can keep it anywhere in your file.

    SCSS CSS
    _sassPartial.scss
    $width: 5em;
    style.scss
    @import "partials/sassPartial";
    #main {
    width: $width;
    }
    #main {
    width: 5em;
    }

Interpolation #{}

We can use variables in selector, property and property values using interpolation.

SCSS CSS
$name: myElement;
$attr: border;
$font-size: 12px;
$line-height: 15px;

p.#{$name} {
#{$attr}-color: blue;
font: #{$font-size}/#{$line-height};
}
p.myElement {
border-color: blue;
font: 12px/15px;
}

Directive

SASS provides directives like @if, @while, @each, @for. These SASS directive behaves like in any other programming language. We can use these for alike tasks or in functions or mixins.

SCSS CSS
@mixin style-area($type){
div {
@if $type == water {
color: blue;
} @else if $type == land {
color: green;
} @else {
color: black;
}
}
}

.my-land{
@include style-area(land);
}
.my-land div {
color: green;
}

SCSS CSS
@mixin style-menu-items($maxLevel){
@for $i from 1 through $maxLevel {
.menu-item-#{$i} { margin-left: 2em * $i; }
}
}

div.menu4{
@include style-menu-items(4);
}
div.menu4 .menu-item-1 {
margin-left: 2em;
}
div.menu4 .menu-item-2 {
margin-left: 4em;
}
div.menu4 .menu-item-3 {
margin-left: 6em;
}
div.menu4 .menu-item-4 {
margin-left: 8em;
}

SCSS CSS
@each $menu in home, user, nav, about, help {
.#{$menu}-icon {
background-image: url('/images/#{$menu}.png');
}
}
.home-icon {
background-image: url("/images/home.png"); }

.user-icon {
background-image: url("/images/user.png"); }

.nav-icon {
background-image: url("/images/nav.png"); }

.about-icon {
background-image: url("/images/about.png"); }

.help-icon {
background-image: url("/images/help.png"); }

SCSS CSS
$itemCount: 5;
@while $itemCount > 0 {
.menu-item-#{$itemCount} { background-color: #F1AA22 * $itemCount; }
$itemCount: $itemCount - 2;
}
.menu-item-5 {
background-color: #ffffaa; }

.menu-item-3 {
background-color: #ffff66; }

.menu-item-1 {
background-color: #f1aa22; }

Function

Function directives also behave like functions in any other programming language. They can accept certain parameters, process them and return a result. Functions can be called for styling with some logic.

SCSS CSS
@function parent-height($n, $child-div-height, $p-height) {
@return $n * $child-div-height + $p-height ;
}

#parentDiv { width: parent-height(5, 15, 5); }
#parentDiv {
width: 80;
}

Comments

SCSS supports both single and multi line comments. Multi line comments are preserved in compiled CSS but single line comments are removed while conversion from SCSS to css as a single line comment is not supported by CSS.

SASS caches the compiled templates and partials to speed up compilation process in SASS-cache folder in the root directory.

References

  1. http://sass-lang.com
  2. http://ryanchristiani.com/getting-started-with-grunt-and-sass/
  3. https://www.sitepoint.com/whats-difference-sass-scss/