SCSS in a Nutshell2015/07/20
The complete Sass/SCSS reference is located here.
Installation
Install Sass using Ruby
gem install sassHave Sass watch over a file, and specify the output destination
sass --watch main.scss:main.cssYou will almost never use this command. Instead we use Grunt to handle this.
Install Sass syntax highlighting in Sublime Text via Package Control https://packagecontrol.io/packages/Syntax%20Highlighting%20for%20Sass
- Enable Package Control
- Open the Sublime Text console.
ctrl+`ORView > Show Console - Run the Python code found at https://packagecontrol.io/installation
- Open the Sublime Text console.
- Install the Syntax Highlighting for Sass package
- Open the Command Pallete.
ctrl+shift+p(Win/Linux) ORcmd+shift+p(OSX) - Select Package Control: Install Package (and wait a bit)
- Select Syntax Highlighting for Sass
- Open the Command Pallete.
Partials
All .scss files are compiled into their respective .css file. Partials which are prefixed with an underscore will not generate their own .css file. They exist for inclusion from other files.
// _partial.scss
@import 'partial'; // underscore and extension omittedCSS Compliant
All CSS rules and syntax work in Sass. CSS in a Nutshell: /css-in-a-nutshell
Nesting
Selectors can be nested within others and are equivalent to CSS’s space separated selectors.
ul {
list-style-type: none;
li { // equivalent to the selector 'ul li'
display: block;
}
}Parent Selector
The & character represents the current parent selector and allows selectors to be made relative to it.
.button {
background-color: blue;
&:hover { // .button:hover
background-color: red;
}
footer & { // footer .button
background-color: green;
}
&-black { // .button-black
background-color: black;
}
}Nested Properties
Certain properties can also be nested.
blockquote {
font: {
family: "Times New Roman", serif; // font-family
style: italics; // font-style
size: 2rem; // font-size
}
}Extend/Inheritance
Selectors can inherit from other selectors using @extend. If the !optional tag is included, @extend will be ignored if it were to cause an error (e.g. the selector doesn't exist or is conflictory). The % selector is similar to ./# for classes/id's, but exists for the purpose of inheritance and won't be rendered into the output css.
p%awesome { // This ruleset won't be rendered explicitly
font-weight: bold;
}
.message {
border: 1px solid #CCCCCC;
color: #333333;
}
.message-success {
@extend .message;
border-color: green;
p {
@extend %awesome; // @extend successfully runs
@extend .something !optional; // .something doesn't exist; @extend is ignored.
}
a {
@extend %awesome !optional;
// %awesome is defined only for p
// @extend is ignored.
}
}Variables
Variables’ scopes are within the level of selectors they are defined in, unless given the !global flag. The !default flag will set the variable if it isn't already defined.
$size: 15px;
$size: 30px !default; // $size is still 15px
html {
$color: #335544 !global;
background-color: $color;
}
div {
background-color: white;
color: $color;
}Allowed variable types:
- Numbers:
1.2,13,10px - Strings:
"foo",'bar',baz - Colors:
blue,#04A3F9,rgba(255, 0, 0, .5) - Booleans:
true,false - Nulls:
null - Lists (space or comma separated):
1.5em 0 2em,Helvetica, Arial, san-serif - Maps:
(key1: value1, key2: value2)
Interpolation
Interpolation is mainly for using variables in selectors or strings.
$name: foo;
$attr: border;
p.#{$name} { // p.foo
#{$attr}-color: blue; // border-color
}
$text: "#{$name}#{$attr}"; // "fooborder"Operations
Take care that agreeable units are in the arguments.
Numbers and Colors: + - * / % < > <= >= == !=
80px / 320px * 100% == 25%
#010203 + #040506 == #050709 // computed piecewise
16px + 1em // Invalid operation
10px * 10px == 100px*px // Note px*px is not a CSS unitStrings: + == !=
"Foo " + Bar == "Foo Bar"
sans + -serif == sans-serifBooleans: and or not == !=
Mixins
Mixins are reusable groups of CSS declarations which allow variable parameters. (Also accepts the parameters as lists and maps).
@mixin border($width, $style, $color, $radius: 0px) {
// $radius uses default value of 0px if not passed
border: {
color: $color;
style: $style;
width: $width;
}
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
-ms-border-radius: $radius;
border-radius: $radius;
}
}
@mixin box-shadow($shadows...) { // supports var-args
-webkit-box-shadow: $shadows;
-moz-box-shadow: $shadows;
box-shadow: $shadows;
}
.box {
@include border(1px, solid, blue);
@include box-shadow(0px 4px 5px #666, 2px 6px 10px #999);
}
.circle {
@include border(
$width: 5px,
$color: green,
$style: dashed,
$radius: 50%
);
// keyword arguments
}Mixins using a Content Block
@mixin apply-to-main {
#main {
@content;
}
}
@include apply-to-main {
background-color: blue; // #main
#logo { // #main #logo
background-image: url(/logo.gif);
}
}Functions
Functions supports var-args and keyword arguments similar to mixins. For the list of built-in Sass functions: http://sass-lang.com/documentation/Sass/Script/Functions.html
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar {
width: grid-width(5); // 240px
}Control Directives
All values are "truthy" except for false and null.
The @if, @else if, and @else directives:
p {
@if 1 + 1 == 2 { border: 1px solid; } // true
@if "cheese" { border: 2px solid; } // true
@if 5 < 3 { border: 2px dotted; } // false
@if null { border: 3px double; } // false
@if $type == ocean {
color: blue;
} @else if $type == matador {
color: red;
} @else {
color: black;
}
}The @for directive loops (incrementally or decrementally) a variable through a range of integers.
@for $i from 1 through 3 {
.size-#{$i} { width: 2em * $i; }
}The @each directive loops through lists or maps. Also supports multiple assignment.
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
}
}
@each $animal, $color, $cursor in (puma, black, default),
(sea-slug, blue, pointer),
(egret, white, move) {
.#{$animal}-icon {
background-image: url('/images/#{$animal}.png');
border: 2px solid $color;
cursor: $cursor;
}
}The @while directive loops while a condition is true.
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}