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.
Sass | SCSS |
★ // 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.
- module.exports = function(grunt) {
- grunt.initConfig({
- pkg: grunt.file.readJSON('package.json'),
- sass: {
- dist: {
- files: {
-
- 'style/style.css' : 'sass/style.scss'
- }
- }
- }
- });
- grunt.loadNpmTasks('grunt-contrib-sass');
- grunt.registerTask('default',['sass']);
- }
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.
- SCSS doesn’t evaluate plain css. E.x. font: 15px/12px won’t evaluate as it indicates line height font color.
- Use a variable or parenthesis for expressions.
- Width: 100px/2
- $width: 100px; width: $width/2;
- Width: (100px/2)
- Parenthesis for list values doesn’t evaluate.
- font:(italic bold 10px/8px)
- Use function, + for expression.
- margin-left: 5px + 8px/2px;
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
- http://sass-lang.com
- http://ryanchristiani.com/getting-started-with-grunt-and-sass/
- https://www.sitepoint.com/whats-difference-sass-scss/