There are two syntaxes available for Sass.
- known as SCSS (Sassy CSS) (new)
- known as the indented syntax (or “Sass”) (old)
Nested Rules
Allows CSS rules to be nested within one another.
// scss
#main p {
color: #00ff00;
width: 97%;
.redbox { background-color: #ff0000; color: #000000; }
}
// css
#main p { color: #00ff00; width: 97%; }
#main p .redbox { background-color: #ff0000; color: #000000; }
Parent Selectors
// scss
a {
font-weight: bold;
text-decoration: none;
&:hover { text-decoration: underline; }
body.firefox & { font-weight: normal; }
}
// css
a { font-weight: bold; text-decoration: none; }
a:hover { text-decoration: underline; }
body.firefox a { font-weight: normal; }
Variables
$width: 5em;
#main { width: $width; }
Defaults can be provided. 10em would only be assigned
if $width had not been assigned to yet.
$width: 5em;
$width: "10em" !default;
#main { width: $width; }
#main { width: 5em; }
Data Types
Strings
Two types of strings:
- Quoted (“sans-serif” or ‘sans-serif’)
- Un-quoted (sans-serif)
Use #{} for string interpolation.
@mixin firefox-message($selector) {
body.firefox #{$selector}:before {
content: "Hi, Firefox users!";
}
}
Lists
$paladins: (allura, hunk, shiro, lance, keith, pidge);
@each $paladin in $paladins {
.#{$paladin}.icon {
background-image: url('/assets/#{$paladin}.png');
}
}
Maps
$map: (key1: value1, key2: value2, key3: value3);
$paladins: (allura: pink, hunk: yellow, shiro: black, lance: blue, keith: red, pidge: green);
@each $paladin, $color in $paladins {
.#{$paladin}.icon {
background-image: url('/assets/#{$paladin}.png');
}
body.#{$paladin} {
background-color: $color;
}
}
Example
Remove duplication by using a map and each.
.application--amp {
.application__card { @include application-invert-color($color-product--amp) }
.application__button { @include application-invert-color($color-product--amp) }
}
.application--tg {
.application__card { @include application-invert-color($color-product--tg) }
.application__button { @include application-invert-color($color-product--tg) }
}
.application--tr {
.application__card { @include application-invert-color($color-product--tr) }
.application__button { @include application-invert-color($color-product--tr) }
}
Can be refactored to:
$product-color-map: (amp: $color-product--amp, tg: $color-product--tg, tr: $color-product--tr);
@each $product, $color in $product-color-map {
.application--#{$product} {
.application__card { @include application-invert-color($color); }
.application__button { @include application-invert-color($color); }
}
}
Colors
See this list.
@import
@import takes a filename to import.
By default, it looks for a Sass file to import directly, but there are a few circumstances under which it will compile to a CSS @import rule:
- If the file’s extension is .css.
- If the filename begins with http://.
- If the filename is a url().
- If the @import has any media queries.
@import 'atomic'; // will load atomic.scss
@import 'atomic-contrib.scss';
Partials
Prefix partials filenames with _. This will instruct sass to not
convert the partial to a css file but instead include the scss code into
the file that is importing the partial.
If you have a _colors.scss, this code would be imported instead of
generating a colors.css file.
@import "colors";
@extend
This allows you to inherit styles from other styles.
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion { background-image: url("/image/hacked.png"); }
.seriousError {
@extend .error;
border-width: 3px;
}
Compiles to:
.error, .seriousError { border: 1px #f00; background-color: #fdd; }
.error.intrusion, .seriousError.intrusion { background-image: url("/image/hacked.png"); }
.seriousError { border-width: 3px; }
Logging
@debugdirective prints the value of an expression to the standard error output stream.@warndirective prints the value of an expression to the standard error output stream.@errordirective throws the value of an expression as a fatal error, including a stack trace.
@debug 10em + 12em;
@warn "Assuming #{$x} to be in pixels";
@error "$x may not be unitless, was #{$x}.";
Line 1 DEBUG: 22em
Loops
@for
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
.item-1 { width: 2em; }
.item-2 { width: 4em; }
.item-3 { width: 6em; }
@each
@each $animal in puma, sea-slug, egret, salamander {
.#{$animal}-icon {
background-image: url('/assets/#{$animal}.png');
}
}
@each $header, $size in (h1: 2em, h2: 1.5em, h3: 1.2em) {
#{$header} {
font-size: $size;
}
}
.puma-icon { background-image: url('/images/puma.png'); }
.sea-slug-icon { background-image: url('/images/sea-slug.png'); }
.egret-icon { background-image: url('/images/egret.png'); }
.salamander-icon { background-image: url('/images/salamander.png'); }
h1 { font-size: 2em; }
h2 { font-size: 1.5em; }
h3 { font-size: 1.2em; }
@while
$i: 6;
@while $i > 0 {
.item-#{$i} { width: 2em * $i; }
$i: $i - 2;
}
.item-6 { width: 12em; }
.item-4 { width: 8em; }
.item-2 { width: 4em; }
@mixin
@mixin large-text {
font: {
family: Arial;
size: 20px;
weight: bold;
}
color: #ff0000;
}
.page-title {
@include large-text;
padding: 4px;
margin-top: 10px;
}
.page-title {
font-family: Arial;
font-size: 20px;
font-weight: bold;
color: #ff0000;
padding: 4px;
margin-top: 10px;
}
mixins can include other mixins.
@mixin compound {
@include highlighted-background;
@include header-text;
}
@mixin highlighted-background { background-color: #fc0; }
@mixin header-text { font-size: 20px; }
mixins can accept arguments.
@mixin sexy-border($color, $width) {
border: {
color: $color;
width: $width;
style: dashed;
}
}
p { @include sexy-border(blue, 1in); }
p {
border-color: blue;
border-width: 1in;
border-style: dashed;
}
mixins can accept a content block. This is similar to ruby’s block/yield syntax.
@mixin apply-to-ie6-only {
* html {
@content;
}
}
@include apply-to-ie6-only {
#logo {
background-image: url(/logo.gif);
}
}
* html #logo {
background-image: url(/logo.gif);
}
@function
$grid-width: 40px;
$gutter-width: 10px;
@function grid-width($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
#sidebar { width: grid-width(5); }
#sidebar { width: 240px; }
Stay sassy 💁
Resources: