A sassy introduction to CSS preprocessing
by Ramón Guijarro
Ramón Guijarro
Creative web developer with an eye for design and communication. JavaScript and React enthusiast. Proud @h4ckademy alumni.
What is it?
A scripting language that is interpreted into CSS, also known as CSS preprocessor
Sass
CSS
Two syntaxes
Sass
SCSS
The old syntax
Indentation and newlines
The new syntax
Brackets and semicolons
You can convert between them with sass-convert
body
font-family: sans-serif
color: black
body {
font-family: sans-serif;
color: black;
}
Why should you use it?
Extends CSS with a bunch of useful features
You can finally have variables! Hooray!
Allows better structuring and modularization
Avoids the use of non-semantic selectors
Say goodbye to .float-left
Improves legibility and maintainability
How do you set it up?
sudo apt-get install ruby-full # Ubuntu, Debian
sudo yum install ruby # Fedora, CentOS, RHEL
sudo pacman -S ruby # Arch Linux
brew install ruby # OS X (Homebrew)
format C: # Windows
Install Ruby
Technically, you don't need Ruby. Implementations in other languages are available thanks to libSass: http://sass-lang.com/libsass.
sudo gem install --no-user-install sass # Globally
gem install sass # For your user
Install Sass
If you install the gem for your user, you'll need to add
the folder with the executable to your PATH.
sass -i
Interactive shell
Convert a file
Watch for changes
sass styles.scss styles.css
sass --watch styles.scss:styles.css # A file
sass --watch cssFolder:scssFolder # A folder
Run Sass
sudo gem install --no-user-install listen # Globally
gem install listen # For your user
Install Listen (optional)
It prevents Sass from polling for changes in some scenarios.
You should be fine without it for now, though.
Install tools (optional)
Syntax highlighter for your editor
- Sublime Text: https://packagecontrol.io/packages/Sass
- Atom: https://atom.io/packages/language-sass
Auto reload plugin for your browser
Alternative setups
No setup
- SassMeister: http://sassmeister.com
- CodePen: http://codepen.io
- JSFiddle: http://jsfiddle.net
Fancy setups
- Task runners / automators
- Grunt with grunt-contrib-sass plugin
- Gulp with gulp-sass or gulp-ruby-sass plugins
- Handled by the server
- Rails with sass-rails gem (default since Rails 3.1)
- Node with node-sass package
- Rails with sass-rails gem (default since Rails 3.1)
How do you use it?
Extensions
main {
margin: 1em auto;
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
main {
margin: 1em auto;
}
main a {
text-decoration: none;
}
main a:hover {
text-decoration: underline;
}
Nested rules
SCSS
CSS
h1 {
font: {
family: sans-serif;
size: 2em;
}
border: {
color: #ffffff;
width: 2px;
}
}
h1 {
font-family: sans-serif;
font-size: 2em;
border-color: #ffffff;
border-width: 2px;
}
Nested properties
SCSS
CSS
$sans-serif-font: 'Droid Sans';
$base-size: 1em;
h1 {
font: {
family: $sans-serif-font;
size: $base-size * 2;
}
}
h1 {
font-family: 'Droid Sans';
font-size: 2em;
}
Variables and operations
SCSS
CSS
$col-width: 40px;
$gutter-width: 10px;
@function grid-width($cols) {
@return $cols * $col-width +
($cols - 1) *
$gutter-width;
}
.container {
width: grid-width(3);
}
.container {
width: 140px;
}
SCSS
CSS
Take a look at http://sass-lang.com/documentation/Sass/Script/Functions.html for all the functions included in the language
Functions
Directives
Media queries
They work just like in regular CSS, but can be nested.
$phone-bp: 320px;
$tablet-bp: 768px;
.sidebar {
display: none;
@media (min-width: $phone-bp) {
display: block;
}
@media (min-width: $tablet-bp) {
display: inline;
}
}
.sidebar {
display: none;
}
@media (min-width: 320px) {
.sidebar {
display: block;
}
}
@media (min-width: 768px) {
.sidebar {
display: inline;
}
}
SCSS
CSS
%error {
color: white;
background-color: red;
border-color: darken(red, 10%);
}
.normal-error {
@extend %error;
border-width: 1px;
}
.highlighted-error {
@extend %error;
border-width: 3px;
}
.normal-error, .highlighted-error {
color: #ffffff;
background-color: #ff0000;
border-color: #cc0000;
}
.normal-error {
border-width: 1px;
}
.highlighted-error {
border-width: 3px;
}
Extend and placeholders
SCSS
CSS
Extends are fixed and prevent from repetition.
@mixin banner($color) {
background-color: $color;
color: lighten($color, 20%);
}
.warning {
@include banner(#ffff00);
}
.error {
@include banner(#ff0000);
}
.warning {
background-color: #ffff00;
color: #ffff66;
}
.error {
background-color: #ff0000;
color: #ff6666;
}
Include and mixins
SCSS
CSS
Mixins can be variable and don't prevent from repetition.
@for $index from 1 through 3 {
.item-#{$index} {
height: 2em * $index;
}
}
.item-1 {
height: 2em;
}
.item-2 {
height: 4em;
}
.item-3 {
height: 6em;
}
Control directives (I)
SCSS
CSS
These allow you to write very fancy stuff, but are rarely used.
You probably want to use third-party libraries instead.
@each $item in new, open, save {
.#{$item}-icon {
background-image:
url('#{$item}.png');
}
}
.new-icon {
background-image: url('new.png');
}
.open-icon {
background-image: url('open.png');
}
.save-icon {
background-image: url('save.png');
}
Control directives (II)
SCSS
CSS
These allow you to write very fancy stuff, but are rarely used.
You probably want to use third-party libraries instead.
Control directives (III)
$prefixes: moz, webkit, o, ms;
$prefixer-enabled: true;
@mixin border-radius($radius) {
@if $prefixer-enabled {
@each $prefix in $prefixes {
-#{$prefix}-border-radius: $radius;
}
}
border-radius: $radius;
}
button {
@include border-radius(10px);
}
button {
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
-o-border-radius: 10px;
-ms-border-radius: 10px;
border-radius: 10px;
}
SCSS
CSS
button {
border-radius: 10px;
}
$prefixer-enabled: true
$prefixer-enabled: false
These allow you to write very fancy stuff, but are rarely used.
You probably want to use third-party libraries instead.
Import and partials
* {
margin: 0;
padding: 0;
}
body {
font-family: 'Open Sans';
background-color: #eeeeec;
}
* { margin: 0; padding: 0; }
CSS
SCSS
$body-font: 'Open Sans';
$body-bg-color: #eeeeec;
_reset.scss
_variables.scss
@import 'reset', 'variables';
body {
font-family: $body-font;
background-color: $body-bg-color;
}
main.scss
main.css
All together
Code example
What else can you use?
Frameworks
- Compass: http://compass-style.org
- Foundation: http://foundation.zurb.com
- Bootstrap: http://getbootstrap.com/css/#sass
- Bourbon Refills: http://refills.bourbon.io
Mixin libraries
- Bourbon: http://bourbon.io
Grid systems
- Susy: http://susy.oddbird.net
- Bourbon Neat: http://neat.bourbon.io
Complements
Other preprocessors
- Less: http://lesscss.org
- Stylus: https://learnboost.github.io/stylus
Postprocessors
- PostCSS: https://github.com/postcss/postcss
Future versions of CSS
Alternatives
Thank you
A sassy introduction to CSS preprocessing
By Ramón Guijarro
A sassy introduction to CSS preprocessing
Slides from an introductory talk to CSS preprocessing with Sass. Take a look at this GitHub repository for a code example that shows all the features of the language explained here in practice: https://github.com/soyguijarro/sass-talk
- 1,666