Work and play with SASS & Compass

Preview:

DESCRIPTION

Still there are some controversies about whether precompiling CSS is a good or a bad idea. Sometimes this leads to fights, struggles and name-calling. This talk is almost clean of it.I'll show examples of "SASS" and "Compass"" from his day-to-day work and what you can do if you unleash the power of preprocessing.

Citation preview

yWork & Play(Verantwortungsvolles) Arbeiten mit SASS & Compass

Andreas Dantz0

@dantz — ad@vortrieb.net

CSS zu kompilieren ist total bescheuert, unnötig und führt zu minderwertigen Ergebnissen. Wer so etwas nutzt, schlägt auch wehrlose Omas auf der Straße.

Andreas Dantz, anno 2009

CSS 3h!p://www.flickr.com/photos/bcnbits/

.css

.sass

.scss

CSS

.box {

margin: 1em;

}

.box .content {

border: 1px solid #f00;

}

SASS

.box

margin: 1em

.content

border: 1px solid #f00

SCSS

.box {

margin: 1em

.content {

border: 1px solid #f00;

}

}

Variablen1

erste Schri!e in Richtung Programmiersprache

$color-main: #00aeef;$baseline: 16px;

strong { color: $color-main; }p { margin-bottom: $baseline; }

SCSS

strong { color: #00aeef; }p { margin-bottom: 16px; }

CSS

4px + 4px;4px - 4px;4px * 2;4px / 2;

8px;0px;8px;2px;

SCSS

CSS

halbe Grundlinie als Margin

halbe Grundlinie abzüglich Rahmen als Padding

$baseline: 32px;$border-width: 4px;

.box { border: $border-width solid $color-main; margin: $baseline / 2; padding: $baseline / 2 - $border-width;}

SCSS

.box { border: 4px solid #00aeef; margin: 16px; padding: 12px;}

CSS

round(4.3);ceil(4.2);floor(4.6);abs(-12);percentage(120/960);

SCSS

4;5;4;12;12,5%;

CSS

$color-main: #00aeef;

a { color: $color-main; }a:hover,a:focus { color: lighten($color-main, 15%); }

SCSS

a { color: #00aeef; }

a:hover,a:focus { color: #3dcaff;}

CSS

adjust-hue($color, $degrees)

lighten($color, $amount)

darken($color, $amount)

saturate($color, $amount)

desaturate($color, $amount)

grayscale($color)

complement($color)

invert($color)

SCSS

@if

@for

@each

@while

SCSS

SCSS@import "compass/reset","compass/css3"; @import "layout";

// ============== Vars =====================$items: 6; // number of items$arc: 90; // arc of the circle$angle: $arc/$items; // angle between items$space:170; // a value in pixel. It's the space between the red circle and the items$circleCenterX: 30; // the X coord of the red circle center $circleCenterY: 30; // the Y coord of the red circle center $disappearDelay: 50;

// Generate items position + keyframes animation@for $i from 1 through $items {     // I'm not really good in math, so I suppose that they have a better way to calcul coordinates :)    $rad: ( $angle * ($i - 1) + $angle/2 ) * (pi()/180);    $x:round(($circleCenterX + $space) * cos($rad) );    $y:round(-($circleCenterY + $space) * sin($rad) );                                 // Coords for the rebound during the animation    $xm: round($x * 1.15);    $ym: round($y * 1.15);         $disappearDelay: $disappearDelay * 1.35;         // CSS checkbox + label tricks    #menu:checked ~ .items li:nth-child(#{$i}) {         -webkit-animation-name: "appear-'#{$i}'";         -webkit-animation-duration: 240ms;         -webkit-animation-iteration-count: 1;         -webkit-animation-fill-mode: forwards;          -webkit-animation-delay: (20 * $i)+ms;     }         #menu:not(:checked) ~ .items li:nth-child(#{$i}) {        -webkit-animation-name: "disappear-'#{$i}'";        -webkit-animation-duration: (320 + $disappearDelay)+ms;        -webkit-animation-iteration-count: 1;        -webkit-animation-fill-mode: forwards;     }                       // Generate keyframes     // ======================    // Sass interpolation doesn't work with keyframe. CF : https://github.com/nex3/sass/issues/46    // so I use a tricks ==> "appear-'#{$i}'" - And it doesn't work in Firefox.        @-webkit-keyframes "appear-'#{$i}'" {         0% {           -webkit-transform:translate3d(0, 0, 0px) rotateZ(270deg);            -webkit-animation-timing-function:cubic-bezier(1,.6,.57,.75);        }         80% {            -webkit-animation-timing-function:cubic-bezier(.45,.97,.51,.78);            -webkit-transform:translate3d($xm+px, $ym+px,0px) rotateZ(0deg);         }        100% {            -webkit-transform:translate3d($x+px, $y+px,0px);         }    }         @-webkit-keyframes "disappear-'#{$i}'" {         0% {            -webkit-transform:translate3d($x+px, $y+px,0px) rotateZ(0deg);            -webkit-animation-timing-function:cubic-bezier(1,.6,.57,.75);        }         70% {             -webkit-transform:translate3d($xm+px, $ym+px,0px) rotateZ(360deg);            -webkit-animation-timing-function:cubic-bezier(.45,.97,.51,.78)        }        100% {           -webkit-transform:translate3d(0,0,0px) rotateZ(540deg);         }    }           }

h!ps://github.com/Victa/path-menu

und andere Sauerein mit SelektorenNesting

2

.box { margin: 12px; h2 { font-size: $baseline * 2; }}

SCSS

.box { padding: 12px;}.box h2 { font-size: 64px;}

CSS

article {header, footer { background-color: $color-main; }

}

SCSS

article header, article footer { background-color: #00aeef;}

CSS

$color-main: #00aeef;

a { color: $color-main; &:hover, &:focus { color: lighten($color-main, 15%); }}

SCSS

a { color: #00aeef; }

a:hover, a:focus { color: #3dcaff;}

CSS

button { color: #fff; background: linear-gradient(top,

$color-main 0%, darken($color-main, 5%) 100%); .no-cssgradients & { background: #eee };}

SCSS

button { background: linear-gradient(top,

#00aeef 0%, #009bd5 100%);}.no-cssgradients button { background: #eee;}

CSS

.message { background-color: lighten($color-main, 40%); border: $border-width solid $color-main;

h3 { font-size: $baseline / 2; }

p:last-child { margin-bottom: 0; }}

.error { @extend .message; background-color: lighten($color-error, 40%); border-color: $color-error;}

SCSS

.message, .error { background-color: #bcedff; border: 4px solid #00aeef; padding: 1em; margin-bottom: 32px;}

.message h3, .error h3 { font-size: 16px; margin-bottom: 16px;}

.message p:last-child, .error p:last-child { margin-bottom: 0;}

.error { background-color: #ffcccc; border-color: red;}

CSS

flickr.com/photos/basibanget

#page-wrapper #page #main-wrapper #main #content,#page-wrapper #main .column#content,.section .region #block-system-main.block { font-weight: bold; h2.active, h2, .visuallyhidden { color: #fff; a, .button { &:link, &:visited { background-color: #f00 } &:hover, &focus { #background-color: #f0f; } } }}

SCSS

#page-wrapper #page #main-wrapper #main #content,#page-wrapper #main .column#content,.section .region #block-system-main.block { font-weight: bold;}

#page-wrapper #page #main-wrapper #main #content h2.active, #page-wrapper #page #main-wrapper #main #content h2, #page-wrapper #page #main-wrapper #main #content .visuallyhidden,#page-wrapper #main .column#content h2.active,#page-wrapper #main .column#content h2,#page-wrapper #main .column#content .visuallyhidden,.section .region #block-system-main.block h2.active,.section .region #block-system-main.block h2,.section .region #block-system-main.block .visuallyhidden { color: #fff;}

#page-wrapper #page #main-wrapper #main #content h2.active a:link, #page-wrapper #page #main-wrapper #main #content h2.active a:visited, #page-wrapper #page #main-wrapper #main #content h2.active .button:link, #page-wrapper #page #main-wrapper #main #content h2.active .button:visited, #page-wrapper #page #main-wrapper #main #content h2 a:link, #page-wrapper #page #main-wrapper #main #content h2 a:visited, #page-wrapper #page #main-wrapper #main #content h2 .button:link, #page-wrapper #page #main-wrapper #main #content h2 .button:visited, #page-wrapper #page #main-wrapper #main #content .visuallyhidden a:link, #page-wrapper #page #main-wrapper #main #content .visuallyhidden a:visited, #page-wrapper #page #main-wrapper #main #content .visuallyhidden .button:link, #page-wrapper #page #main-wrapper #main #content .visuallyhidden .button:visited,#page-wrapper #main .column#content h2.active a:link,#page-wrapper #main .column#content h2.active a:visited,#page-wrapper #main .column#content h2.active .button:link,#page-wrapper #main .column#content h2.active .button:visited,#page-wrapper #main .column#content h2 a:link,#page-wrapper #main .column#content h2 a:visited,#page-wrapper #main .column#content h2 .button:link,#page-wrapper #main .column#content h2 .button:visited,#page-wrapper #main .column#content .visuallyhidden a:link,#page-wrapper #main .column#content .visuallyhidden a:visited,#page-wrapper #main .column#content .visuallyhidden .button:link,#page-wrapper #main .column#content .visuallyhidden .button:visited,.section .region #block-system-main.block h2.active a:link,.section .region #block-system-main.block h2.active a:visited,.section .region #block-system-main.block h2.active .button:link,.section .region #block-system-main.block h2.active .button:visited,.section .region #block-system-main.block h2 a:link,.section .region #block-system-main.block h2 a:visited,.section .region #block-system-main.block h2 .button:link,.section .region #block-system-main.block h2 .button:visited,.section .region #block-system-main.block .visuallyhidden a:link,.section .region #block-system-main.block .visuallyhidden a:visited,.section .region #block-system-main.block .visuallyhidden .button:link,.section .region #block-system-main.block .visuallyhidden .button:visited { background-color: #f00;}

#page-wrapper #page #main-wrapper #main #content h2.active a:hover, #page-wrapper #page #main-wrapper #main #content h2.active a focus, #page-wrapper #page #main-wrapper #main #content h2.active .button:hover, #page-wrapper #page #main-wrapper #main #content h2.active .button focus, #page-wrapper #page #main-wrapper #main #content h2 a:hover, #page-wrapper #page #main-wrapper #main #content h2 a focus, #page-wrapper #page #main-wrapper #main #content h2 .button:hover, #page-wrapper #page #main-wrapper #main #content h2 .button focus, #page-wrapper #page #main-wrapper #main #content .visuallyhidden a:hover, #page-wrapper #page #main-wrapper #main #content .visuallyhidden a focus, #page-wrapper #page #main-wrapper #main #content .visuallyhidden .button:hover, #page-wrapper #page #main-wrapper #main #content .visuallyhidden .button focus,#page-wrapper #main .column#content h2.active a:hover,#page-wrapper #main .column#content h2.active a focus,#page-wrapper #main .column#content h2.active .button:hover,#page-wrapper #main .column#content h2.active .button focus,#page-wrapper #main .column#content h2 a:hover,#page-wrapper #main .column#content h2 a focus,#page-wrapper #main .column#content h2 .button:hover,#page-wrapper #main .column#content h2 .button focus,#page-wrapper #main .column#content .visuallyhidden a:hover,#page-wrapper #main .column#content .visuallyhidden a focus,#page-wrapper #main .column#content .visuallyhidden .button:hover,#page-wrapper #main .column#content .visuallyhidden .button focus,.section .region #block-system-main.block h2.active a:hover,.section .region #block-system-main.block h2.active a focus,.section .region #block-system-main.block h2.active .button:hover,.section .region #block-system-main.block h2.active .button focus,.section .region #block-system-main.block h2 a:hover,.section .region #block-system-main.block h2 a focus,.section .region #block-system-main.block h2 .button:hover,.section .region #block-system-main.block h2 .button focus,.section .region #block-system-main.block .visuallyhidden a:hover,.section .region #block-system-main.block .visuallyhidden a focus,.section .region #block-system-main.block .visuallyhidden .button:hover,.section .region #block-system-main.block .visuallyhidden .button focus { #background-color: #f0f;}

CSS

Die drei Legitimationen fürs Nesting in SASS

1. Ich möchte mehr Übersicht in meinem Stylesheet

2. Ich hä!e die Selektoren auch manuell in CSS kombiniert

3. Ich will mir Tipparbeit sparen

Ordnung scha" OrdnungArchitektur

3

application.scss_base.scss_layout.scss_menu.scss_mixins.scss…

@include "base";@include "mixins";@include "layout";@include "menu";…

keine Ausgabe!

jetzt bin ich offiziell CSS-ProgrammiererMixins

4

@mixin link-effect { color: $color-main; &:hover, &:focus {

color: darken($color-main, 30%); }}

nav a { @include link-effect; }

SCSS

nav a { color: #00aeef;}

nav a:hover, nav a:focus { color: #003f56;}

CSS

Mixins sollst Du nur benutzen,wenn Parameter übergeben.Sonst wirst das Stylesheet Du beschmutzen,kannst du damit wirklich leben?

@mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; border-radius: $radius;}

.box { @include border-radius(5px); }

SCSS

.box { -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;}

CSS

@mixin linkcolor($link:black, $hover:red) { color: $link; &:hover, a:focus { color: $hover; }}

a { @include linkcolor($hover:yellow); }

SCSS

a { color: black; }a:hover, a:focus { color: yellow; }

CSS

@mixin linkcolor($dark: false) { @if $dark == true { color: black; &:hover { color: blue; } } @else { color: white; &:hover { color: #ccc; } }}

a { @include linkcolor(); }a.alt { @include linkcolor(true); }

SCSS

a { color: white; }a:hover { color: #ccc; }a.alt { color: black; }a.alt:hover { color: blue; }

CSS

5

@import "compass";

.box { @include border-radius(8px); @include background(linear-gradient(#000, #333));}

SCSS

.box { -moz-border-radius: 8px; -webkit-border-radius: 8px; -ms-border-radius: 8px; border-radius: 8px; background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #000000), color-stop(100%, #333333)); background: -webkit-linear-gradient(#000000, #333333); […] background: linear-gradient(#000000, #333333);}

CSS

header { background: image-url('logo.jpg'); h1 { width: image-width('logo.jpg'); height: image-height('logo.jpg'); }}

SCSS

header { background: url('/images/logo.jpg?1321202172');}

header h1 { width: 346px; height: 400px;}

CSS

.unlocked { background: inline-image('unlocked.png');}

SCSS

.unlocked { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAABkCAMAAACxdeD+AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODVBQkU5NzQ1NjU1MTFFMUFGODdFNTI1QzQwQzYzNkMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6ODVBQkU5NzU1NjU1MTFFMUFGODdFNTI1QzQwQzYzNkMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowQjAyREI0RDU2NEUxMUUxQUY4N0U1MjVDNDBDNjM2QyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQjAyREI0RTU2NEUxMUUxQUY4N0U1MjVDNDBDNjM2QyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pvv5YQwAAACEUExURcvLy/Pz87CwsImJic/Pz/v7++Tk5K+vr62trd3d3YCAgLGxsaKiot/f38rKyri4uPf398fHx/Dw8Pj4+LW1tenp6ZaWlqurq66uroODg8jIyIuLi5ycnIqKiu/v7/r6+oWFhZubm9jY2KampuHh4ZiYmNLS0tnZ2YSEhH9/f7Kysv///3IN8QsAAACqSURBVHja7NXnDoIwFAXgikXcey/cem7f//2sDV3E8EdRY3qTNvTLpaeEEJh4Uizgn2L/clxucziZAlgdPIzXaA8SbIYu1nCOhZiDuXhFIuduk1xsIHr0L2YKO0zVGHueihNxhXXoulXMOSOD1XLRpu8s8hZl1Rv9+tuUh3yls4zbP7bnd4NC+vvSySAZVGs76U55rYfdU3+v5AXlLEv3rfiJKPw7CvAuwAAQmUbpoWRiDAAAAABJRU5ErkJggg==');}

CSS

@import "icon/*.png";@include all-icon-sprites($dimensions:true); SCSS

.icon-sprite, .icon-plus, .icon-minus { background: url('/images/icon-sd55776.png'); no-repeat;}

.icon-plus { background-position: 0 0; height: 14px; width: 24px;}

.icon-minus { background-position: -15px 0; height: 7px; width: 24px;}

CSS

das Chaos beherrschenResponsive

6

@media screen and (min-width: 480px) { nav li { float: none; }}

$break-phone: 320px;

nav li { float: left; @media screen and (max-width: $break-phone + 1) { float: none;

}}

SCSS

nav li { float: left;}

@media screen and (max-width: 321px) { nav li { float: none; }}

CSS

#blow { @include border-radius(50%); background-color: $color-main;}

@for $i from 1 through 500 { @media screen and (min-width: $break-phone + $i) { #blow { width: #{600 - $i}px; height: #{600 - $i}px; } }}

SCSS

[…]

@media screen and (min-width: 335px) { #blow { width: 585px; height: 585px; } }@media screen and (min-width: 336px) { #blow { width: 584px; height: 584px; } }@media screen and (min-width: 337px) { #blow { width: 583px; height: 583px; } }@media screen and (min-width: 338px) { #blow { width: 582px; height: 582px; } }@media screen and (min-width: 339px) { #blow { width: 581px; height: 581px; } }@media screen and (min-width: 340px) { #blow { width: 580px; height: 580px; } }

[…]

CSS

$break-small: 320px;$break-large: 1024px;

@mixin respond-to($media) { @if $media == mobile { @media only screen and (max-width: $break-mobile) { @content; } } @else if $media == medium { @media only screen and (min-width: $break-mobile + 1) and (max-width: $break-large - 1) { @content; } } @else if $media == widescreen { @media only screen and (min-width: $break-large) { @content; } }}

SCSS

.avatar { border: 1px solid $color-main; @include respond-to(mobile) { width: 100% ;} @include respond-to(medium) { width: 150px; } @include respond-to(widescreen) { float: none; }}

.avatar { border: 1px solid #00aeef; }

@media only screen and (max-width: 320px) { .avatar { width: 100%; }}

@media only screen and (min-width: 321px) and (max-width: 1023px) { .avatar { width: 150px; }}

@media only screen and (min-width: 1024px) { .avatar { float: none; }}

CSS

woher? wie? wie viel?Workflow

7

CodeKit

Fragen?Danke

8

Recommended