Sass
A "talk" by Eric Wood
Syntactically Awesome Style Sheets
- CSS preprocessor (compiles to raw CSS)
- Superset of CSS syntax
- Has cool acronym
- Is way better than LESS
Nesting
.foo {
h1 {
font-size: 10000px;
}
a {
color: red;
text-decoration: none;
}
}
.foo h1 {
font-size: 10000px;
}
.foo a {
color: red;
text-decoration: none;
}
.container {
&--selected {
background-color: red;
}
&__header {
font-size: 24px;
}
&__items {
float: left;
}
}
.container--selected {
background-color: red;
}
.container__header {
font-size: 24px;
}
.container__items {
float: left;
}
Using & can make BEM easier
Variables are useful
//Blue
$blue: #0F346C;
$lightBlue: #7581a7;
$darkBlue: #00214C;
$borderBlue: #1f2140;
$borderDarkBlue: #1f2140;
$toggleHoverBlue: #002F6C;
.apron {
background-color: $blue;
}
The ampersand is awesome
.foo {
background-color: blue;
html.rgba & {
background-color: rgba(255, 82, 0, 0.5);
}
}
.foo {
background-color: blue;
}
html.rgba .foo {
background-color: rgba(255, 82, 0, 0.5);
}
@mixin btnFont {
font-family: Michael Cera MS;
font-weight: bold;
}
.cool-btn {
@include btnFont;
}
.cool-btn {
font-family: Michael Cera MS;
font-weight: bold;
}
Mixins are cool
...they can take arguments and whatnot
@mixin arrow($size: 10px, $color: #000, $dir: "down") {
content: "";
display: inline-block;
vertical-align: top;
width: 0;
height: 0;
border-style: solid;
border-width: 0 $size $size $size;
border-color: transparent transparent $color transparent;
}
.red-arrow {
@include arrow($color: red);
}
.red-arrow {
content: "";
display: inline-block;
vertical-align: top;
width: 0;
height: 0;
border-style: solid;
border-width: 0 10px 10px 10px;
border-color: transparent transparent red transparent;
}
Extending is a good feature as well
%base_arrow {
content: "";
display: inline-block;
vertical-align: top;
width: 0;
height: 0;
border-style: solid;
}
.red-arrow {
@extend %base_arrow;
color: red;
}
.green-arrow {
@extend %base_arrow;
color: green;
}
.red-arrow, .green-arrow {
content: "";
display: inline-block;
vertical-align: top;
width: 0;
height: 0;
border-style: solid;
}
.red-arrow {
color: red;
}
.green-arrow {
color: green;
}
You can do math with it
@mixin btnProportions($font-size: 18px) {
$height: round($font-size * 0.71);
font-size: $font-size;
line-height: ($height * 3.9);
height: ($height * 3.9);
padding: 0 round($height * 2.5);
}
.big-button {
@include btnProportions($font-size: 100px);
}
.big-button {
font-size: 100px;
line-height: 276.9px;
height: 276.9px;
padding: 0 178px;
}
Colors are just, like, numbers when you really think about it, ya know?
$red: rgb(255,0,0);
$lessRed: transparentize($red, 0.3);
$aLittleMoreRed: opacify($lessRed, 0.2);
$grayscale: grayscale($aLittleMoreRed);
$inverted: invert($red);
p {
color: #010203 + #040506;
color: $lessRed;
color: $aLittleMoreRed;
color: $grayscale;
color: $inverted;
}
p {
color: #050709;
// transparentize
color: rgba(255, 0, 0, 0.7);
// opacify
color: rgba(255, 0, 0, 0.9);
// grayscale
color: rgba(128, 128, 128, 0.9);
// invert
color: cyan;
}
Flow control
@mixin arrow($size: 10px, $color: #000, $dir: "down") {
@extend %base_arrow;
@if $dir == "up" {
border-width: 0 $size $size $size;
border-color: transparent transparent $color transparent;
}
@if $dir == "down" {
border-width: $size $size 0 $size;
border-color: $color transparent transparent transparent;
}
@if $dir == "left" {
border-width: $size $size $size 0;
border-color: transparent $color transparent transparent;
}
@if $dir == "right" {
border-width: $size 0 $size $size;
border-color: transparent transparent transparent $color;
}
}
$browsers: ('Chrome', 'Firefox', 'IE', 'Opera');
$things: 'foo', 'bar', 'baz';
$matrix: ((1,0,0),
(0,1,0),
(0,0,1));
Arrays
Maps
@mixin colors($text, $background, $border) {
color: $text;
background-color: $background;
border-color: $border;
}
$map: (
text: black,
background: blue,
border: red
);
.foo {
@include colors($map...);
}
.foo {
color: black;
background-color: blue;
border-color: red;
}
.loader {
@for $i from 1 through 5 {
&:nth-child(#{$i}) {
animation-name: pop-in-#{$i};
}
}
}
For loops
.loader:nth-child(1) {
animation-name: pop-in-1;
}
.loader:nth-child(2) {
animation-name: pop-in-2;
}
.loader:nth-child(3) {
animation-name: pop-in-3;
}
.loader:nth-child(4) {
animation-name: pop-in-4;
}
.loader:nth-child(5) {
animation-name: pop-in-5;
}
$colors: (#A2141F, #7C2020, #4C2020);
$padding: 5px;
@for $i from 2 through 4 {
.t#{$i} {
$i: $i - 1;
background-color: nth($colors, $i);
left: $padding*$i;
}
}
.t2 {
background-color: #A2141F;
left: 5px;
}
.t3 {
background-color: #7C2020;
left: 10px;
}
.t4 {
background-color: #4C2020;
left: 15px;
}
You can do things with ranges and whatever
It even does some neat "destructuring"
$coolThings: (
("computers", red),
("dogs", orange),
("sunglasses", green)
);
@each $item, $color in $coolThings {
.#{item} {
background: $color;
}
}
.item {
background: red;
}
.item {
background: orange;
}
.item {
background: green;
}
Functions
@function square($a) {
@return $a * $a;
}
.foo {
left: square(10);
}
Caveats
Nesting is good and bad
- Structuring your code all pretty is great!
- SUPER specific CSS selectors, however, are bad
- Not reusable, more expensive to draw
- Avoid nesting deeper than, idk, like 3 levels?
- Follow that BEM example from earlier!
- Your code will be gorgeous
- It only generates single class selectors! Woo!
You can write some really confusing code
- These features are fun, but only in moderation
- If you're doing a bunch of logic in your CSS maybe you should rethink how your app works
- Most of the cooler features are more for writing libraries than day-to-day work
Additional Resources
- Sassmeister - good for testing things out
- Official Docs
Sass
By Eric Wood
Sass
- 819