SlideShare a Scribd company logo
1 of 156
Download to read offline
Sass & Compass
Sass &

http://sass-lang.com/   http://compass-style.org/
Question #1


Do you write
   CSS ?
Question #2


 Do you love
(writing) CSS ?
Question #3


 Did you love
(writing) CSS ?
Good News #1


 Sass makes
CSS fun again
Good News #2


Sass will make you
  love CSS again
Good News #3


Compass will make you
  love CSS3 again
Who ?
Julien Cabanès
I care about Front End @ZeeAgency
I reply to julien@zeeagency.com
I tweet sometimes @JulienCabanes
I share some code to github.com/ZeeAgency
Things to remember today



         #1
SYFK !
Save Your F... Keyboard !
Save Your F... Keyboard !
Things to remember today



         #2
Be Lazy
Lazier is Faster
Think yourself as
 Indiana Jones...
Think yourself as
      Indiana Jones...

• You have to kill this son of a b... !
Think yourself as
      Indiana Jones...

• You have to kill this son of a b... !
• You have a gun.
Think yourself as
      Indiana Jones...

• You have to kill this son of a b... !
• You have a gun.
• Why don’t you just ... use it ?
Think yourself as
     Indiana Jones...

• You have to style this website !
• You have a computer.
• Why don’t you just ... use it ?
End of the Story

Back to the Code
CSS : The Good Parts
•   CSS Syntax is easy

•   Selector Query Language is nice

•   Cascading is nice

•   Functions.Yes, CSS have functions

    •   CSS2 : attr(), counter(), url()

    •   CSS3 : calc(), translateX(), rotate()...

•   Media Queries

•   and more...
CSS : The Bad Parts
•   Variables... come on ! (Still draft)

•   Selectors vs. DRY

•   Modularity : many files === many HTTP requests

•   Functions : Can’t write your owns

•   Separation of Concerns is almost impossible

•   CSS3 is great but vendors prefixing, damn !

•   and more !
Solution #1

Wait for CSS4 ?
Solution #2

Abstraction
Solution #2

             Abstraction
“ It’s nothing to be scared of ” - Chris Eppstein
      creator of Compass & Sass Core team member
Good Abstraction


     How ?
Good Abstraction

Keep the Good Parts
Good Abstraction

 Keep the Good Parts

CSS is easy, Keep it easy
Good Abstraction

Keep the Good Parts

  Keep the Syntax
Good Abstraction

Forget the Bad Parts
Good Abstraction

  Forget the Bad Parts

CSS is clearly not enough
Good Abstraction

Forget the Bad Parts

Enhance the Syntax
Good Abstraction


CSS Pre-Processors
  to the rescue
Quick Overview of CSS Pre-Processors
            LESS       Stylus   Sass/SCSS




          Voluntary omitted of
  Other/PHP/Python CSS preprocessors
        (Turbine, CSS Cacheer...)
Quick Overview of CSS Pre-Processors
              LESS      Stylus   Sass/SCSS
Written in     JS         JS       Ruby
Quick Overview of CSS Pre-Processors
              LESS      Stylus   Sass/SCSS
Written in     JS         JS       Ruby
Quick Overview of CSS Pre-Processors
                 LESS          Stylus       Sass/SCSS
Written in        JS              JS           Ruby

Context      Front & Local   Local / Back   Local / Back
Quick Overview of CSS Pre-Processors
                  LESS          Stylus       Sass/SCSS
Written in         JS              JS           Ruby

Context       Front & Local   Local / Back   Local / Back

     Front could be good way to go
          if this was a polyfill
        but CSS4 doesn’t exist yet
Quick Overview of CSS Pre-Processors
                 LESS          Stylus        Sass/SCSS
Written in        JS              JS           Ruby

Context      Front & Local   Local / Back   Local / Back

Syntax       CSS Superset     Not CSS       CSS Superset
Quick Overview of CSS Pre-Processors
                 LESS          Stylus        Sass/SCSS
Written in        JS              JS           Ruby

Context      Front & Local   Local / Back   Local / Back

Syntax       CSS Superset     Not CSS       CSS Superset
                              Your CSS
                             won’t work
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;
Quick Overview of CSS Pre-Processors
                      LESS             Stylus          Sass/SCSS
Written in             JS                JS               Ruby

Context           Front & Local     Local / Back      Local / Back

Syntax            CSS Superset         JS Like        CSS Superset

Variable Syntax   @color: blue;    variable = blue   $variable: blue;



                                          traction
                                  bad abs
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax       .foo() {}          foo()         @mixin foo() {}
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax       .foo() {}          foo()         @mixin foo() {}



                     implicit abs traction
                       co uld  increase
                       learni ng cur ve
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax       .foo() {}          foo()         @mixin foo() {}



                                                     explicit
                                                    ab s traction
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax       .foo() {}          foo()         @mixin foo() {}



Import                Style            Style        Style & Images !
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in             JS               JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax       .foo() {}          foo()         @mixin foo() {}



Import                Style            Style        Style & Images !
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in              JS              JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax        .foo() {}         foo()         @mixin foo() {}



Import                Style            Style        Style & Images !

Framework         Roll your own   Roll your own        Compass
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Written in              JS              JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax            CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax        .foo() {}         foo()         @mixin foo() {}



Import                Style            Style        Style & Images !

Framework         Roll your own   Roll your own        Compass
Quick Overview of CSS Pre-Processors
                      LESS            Stylus          Sass/SCSS
Run with                JS              JS               Ruby

Context           Front & Local    Local / Back      Local / Back

Syntax     More on this later
                  CSS Superset      Not CSS          CSS Superset

Variable Syntax   @color: blue;   variable = blue   $variable: blue;


Mixins Syntax        .foo() {}         foo()         @mixin foo() {}



Import                Style            Style        Style & Images !

Framework         Roll your own   Roll your own        Compass
Skipping Technical Infos



 gem install sass


  http://sass-lang.com/tutorial.html
Sass
•   One language but 2 syntaxes
    •   Sass : indented syntax, forget { } and ;
    •   SCSS : Sassy CSS === CSS3 superset
•   Means Syntaxically Awesome StyleSheets
•   Should run on your machine, not the server
•   Is watching for folder/file changes and parse
•   Shares a lot of features with LESS & Stylus
SCSS is a CSS3 Superset


•   Every existing CSS will work just fine !

•   You love {...} and ; that’s OK !

•   You want a little more ? Try it !

•   You want a lot more ? Love it !
Ready ?
Killer Feature #1
Variables
SCSS
   $link-color: #b4d455;

a {
	   color: $link-color;
}




                             ⌘S
CSS
a {
	   color: #b4d455;
}
Variables Types
   // With or without unit
$number: 1.2;
$number: 10px;
$number: 20%;

// With or without quotes
$string: "Hello World";
$string: '/img/icons.png';
$string: underline;

// Any kind
$color: #b4d455;
$color: rgba(0, 0, 0, 0.5);
$color: hsl(100deg, 40%, 60%);

// Wow
$boolean: true;
$boolean: false;

// With commas or spaces
$list: 10px 5px 15px;
$list: Helvetica, Arial, sans-serif;
What can we do
with Variables ?
Number Operations
Basic Arithmetic : + - * / %
// Ever need this ?
$lightbox-width: 500px;
$lightbox-height: 400px;
$lightbox-padding: 20px;

.lightbox {
	   position: absolute;
	   top: 50%;

                                 ⌘S
	   left: 50%;
	   margin-top: -$lightbox-height / 2;
	   margin-left: -$lightbox-width / 2;
	   padding: $lightbox-padding;
	   width: $lightbox-width - ($lightbox-padding * 2);
	   height: $lightbox-height - ($lightbox-padding * 2);
}
Number Operations
Talkin’ about division...
// Division happens if.. variable, parentheses or other operation
p {
	   font: 10px / 8px;
  	 $width: 1000px;
	   width: $width / 2;
	   height: (500px / 2);
	   margin-left: 5px + 8px / 2px;
}
Number Operations
Talkin’ about division...
// Division happens if.. variable, parentheses or other operation
p {
	   font: 10px / 8px;             // Plain CSS, no division
  	 $width: 1000px;
	   width: $width / 2;
	   height: (500px / 2);
	   margin-left: 5px + 8px / 2px;
}
Number Operations
Talkin’ about division...
// Division happens if.. variable, parentheses or other operation
p {
	   font: 10px / 8px;             // Plain CSS, no division
  	 $width: 1000px;
	   width: $width / 2;            // Uses a variable, does division
	   height: (500px / 2);
	   margin-left: 5px + 8px / 2px;
}
Number Operations
Talkin’ about division...
// Division happens if.. variable, parentheses or other operation
p {
	   font: 10px / 8px;             // Plain CSS, no division
  	 $width: 1000px;
	   width: $width / 2;            // Uses a variable, does division
	   height: (500px / 2);          // Uses parentheses, does division
	   margin-left: 5px + 8px / 2px;
}
Number Operations
Talkin’ about division...
// Division happens if.. variable, parentheses or other operation
p {
	   font: 10px / 8px;             // Plain CSS, no division
  	 $width: 1000px;
	   width: $width / 2;            // Uses a variable, does division
	   height: (500px / 2);          // Uses parentheses, does division
	   margin-left: 5px + 8px / 2px; // Uses +, does division
}
Number Operations
What about this ?
p {
  $font-size: 10px;
  $line-height: 8px;
  font: $font-size / $line-height;
}
Number Operations
What about this ?
p {
  $font-size: 10px;
  $line-height: 8px;
  font: $font-size / $line-height;
}




                                 ⌘S
Ouch...
p {
  font: 1.25;
}
Interpolation
#{...} avoid operations
p {
  $font-size: 10px;
  $line-height: 8px;
  font: #{$font-size} / #{$line-height};
}
Interpolation
#{...} avoid operations
p {
  $font-size: 10px;
  $line-height: 8px;
  font: #{$font-size} / #{$line-height};
}




                                 ⌘S
Nice
p {
  font: 10px / 8px;
}
Interpolation
#{...} can be used for...
$className: 'foo';
$property: 'padding';

p.#{$className} {
	   #{$property}: 10px;
}




                          ⌘S
Templating ?
p.foo {
	   padding: 10px;
}
Color Operations
Easy to understand
p {
	   color: #010203 + #040506;
}
a {
	   color: #010203 * 2;
}
b {
	   color: rgba(…) + rgba(…);
}




                                ⌘S

p {color: #050709;}
a {color: #020406;}
b {color: rgba(…);}
Number Functions
Sounds familiar
round(), ceil(), floor(), abs(), percentage()

$width: 960px;
$columns: 14;

div {
	   width: round($width / $columns);
}



                                  ⌘S
div {
	   width: 69px;
}
Color Functions
Lazy RGBA, yay !
$my-color: rgba(#b4d455, 0.5);



Mutators
$my-color:   mix(red, blue);
$my-color:   lighten(red, 20%);
$my-color:   darken(red, 20%);
$my-color:   transparentize($my-color, 0.5);
$my-color:   opacify($my-color, 0.5);
$my-color:   grayscale(#b4d455);
$my-color:   invert(#b4d455);
$my-color:   saturate(#b4d455, 10%);
$my-color:   adjust-hue(#b4d455, 10%);

// And more…
Color Functions
Getters (aka Accessors)
$red-component:     red($my-color);
$green-component:   green($my-color);
$blue-component:    blue($my-color);
$alpha-component:   alpha($my-color);

$hue-component:     hue($my-color);
$sat-component:     saturation($my-color);
$light-component:   lightness($my-color);




Setters
$my-color: adjust-color($my-color, $green: -55);
$my-color: scale-color($my-color, $green: 10%);
$my-color: change-color($my-color, $green: 255);
and more...
http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html
Killer Feature #2
Nesting
Properties
article {
	   background: {
	    	 color: transparent;
	    	 image: url("/img/bg.png");
	    	 origin: content-box;
	    	 position: right center;
	    	 repeat: no-repeat;
	    	 size: 100px 100px;
	   }
}



                                     ⌘S
article {
  background-color: transparent;
  background-image: url("/img/bg.png");
  background-origin: content-box;
  background-position: right center;
  background-repeat: no-repeat;
  background-size: 100px 100px;
}
Nesting
Rules
h1 {
	   font-size: 200%;

	   a {
	   	 text-decoration: none;

	   	 &:hover {
	   	 	 text-decoration: underline;
	   	 }
	   }
}



                                 ⌘S
h1 {font-size: 200%;}
h1 a {text-decoration: none;}
h1 a:hover {text-decoration: underline;}
Nesting
Rules
h1 {
	   font-size: 200%;   & means this
	   a {
	   	 text-decoration: none;

	   	 &:hover {
	   	 	 text-decoration: underline;
	   	 }
	   }
}



                                 ⌘S
h1 {font-size: 200%;}
h1 a {text-decoration: none;}
h1 a:hover {text-decoration: underline;}
Warning


Rules Nesting helps you
 write more typing less
Warning


Rules Nesting helps you
 write more typing less
Warning


 But !
Warning


Don’t forget about
 Performance
Warning


Selectors doesn’t need
to reflect your DOM...
Nesting abuse
#wrapper {
	   section {
	   	 article {
	   	 	 h2 {
	   	 	 	 font-size: 200%;
	   	 	 	
	   	 	 	 a {
	   	 	 	 	 color: red;
	   	 	 	 	
	   	 	 	 	 &:hover {
	   	 	 	 	 	 text-decoration: underline;
	   	 	 	 	 }
	   	 	 	 }
	   	 	 }
	   	 	
	   	 	 p {
	   	 	 	 text-align: justify;
	   	 	 }
	   	 }
	   }
}
Control Directives
@if @else @for @each @while

Trivial
@if 1 + 1 == 2 {
	   width: 400px;
} @else {
	   width: 200px;
}




Grids
@for $i from 1 through 10 {
	   .col-#{$i} {
	   	 width: $i * 10px;
	   }
}
Don’t need it ?
Don’t use it !
Modularity
Don’t use @import
http://www.stevesouders.com/blog/2009/04/09/dont-use-import/
Don’t use @import
  Use @import !
Killer Feature #3
@import
                                                                  reset.scss
                                         html, body, div, span, object, iframe,

style.scss                               h1, h2, h3, h4, h5, h6, p, blockquote,
                                         pre, abbr...


@import "reset", "header";
                                                            header.scss
                   ⌘S
                                         header {
                                         	     height: 100px;
                                         	     font-size: 200%;
                                         }


style.css
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote,
pre, abbr...
...
...
...

header {
	     height: 100px;
	     font-size: 200%;
}
Make your own
 Abstractions
Killer Feature #4
Functions
Define with @function
@function round-by($value, $factor: 1) {
	   @return round($value / $factor) * $factor;
}

div {
	   width: round-by(1337px, 20);
}




                                   ⌘S

div {
  width: 1340px;
}
Killer Feature #5
Mixins
Define with @mixin, use with @include
@mixin link-hover-effect($color) {
	   color: $color;
	
	   &:hover {
	   	 color: darken($color, 10%);
	   }
}
article a {
	   @include link-hover-effect( blue);
}



                                  ⌘S
article a {
  color: blue;
}
article a:hover {
  color: #0000cc;
}
Mixins augment style

Functions return values
Pause
Fixing the Bad Parts
Variables

DRY

Modularity

Functions

Separation of Concerns

CSS3 vs.Vendor prefixing
Fixing the Bad Parts
Variables                 Yep !

DRY

Modularity

Functions

Separation of Concerns

CSS3 vs.Vendor prefixing
Fixing the Bad Parts
Variables                       Yep !

DRY                       Nesting & Mixins!

Modularity

Functions

Separation of Concerns

CSS3 vs.Vendor prefixing
Fixing the Bad Parts
Variables                       Yep !

DRY                       Nesting & Mixins!

Modularity                    Imports !

Functions

Separation of Concerns

CSS3 vs.Vendor prefixing
Fixing the Bad Parts
Variables                       Yep !

DRY                       Nesting & Mixins!

Modularity                    Imports !

Functions                       Yep !

Separation of Concerns

CSS3 vs.Vendor prefixing
Fixing the Bad Parts
Variables                       Yep !

DRY                       Nesting & Mixins!

Modularity                    Imports !

Functions                       Yep !

Separation of Concerns           ?
CSS3 vs.Vendor prefixing          ?
Fixing the Bad Parts
Variables                       Yep !

DRY                       Nesting & Mixins!

Modularity                    Imports !

Functions                       Yep !

Separation of Concerns        Mixins ?

CSS3 vs.Vendor prefixing          ?
Separation of Concerns
Clearfix example
<div class="clearfix">
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
</div>

<div class="clearfix">
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
</div>
Separation of Concerns
Clearfix example
<div>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
</div>

<div>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
	   <article>Lorem ipsum</article>
</div>
@mixin Solution
@mixin clearfix {
	   zoom: 1;

	   &:before,
	   &:after {
	   	 content: "0020";
	   	 display: block;
	   	 height: 0;
	   	 visibility: hidden;
	   }

	   &:after {
	   	 clear: both;
	   }
}

div {
	   @include clearfix;
}
@mixin Solution
@mixin clearfix {
	   zoom: 1;

	   &:before,
	   &:after {
	   	 content: "0020";
	   	 display: block;
	   	 height: 0;
	   	 visibility: hidden;
	   }

	   &:after {
	   	 clear: both;
	   }
}

div {
	   @include clearfix;
}
@mixin Solution
     Style will be repeated for every mixin uses
     div {
       zoom: 1;
     }
     div:before, div:after {
       content: "0020";
⌘S     display: block;
       height: 0;
       visibility: hidden;
     }
     div:after {
       clear: both;
     }
@mixin Solution
     Style will be repeated for every mixin uses
     div {
       zoom: 1;
     }
     div:before, div:after {
       content: "0020";
⌘S     display: block;
       height: 0;
       visibility: hidden;
     }
     div:after {
       clear: both;
     }



                      There’s a better way...
Killer Feature #6
Inheritance


@extend  is at selectors
what @mixin is for styles
How @extend works
.box {
	   border: 1px solid blue;
	   padding: 20px;
}
.error-message {
	   @extend .box;
	   border-color: red;
	   color: red;
}




                              ⌘S
.box, .error-message {
  border: 1px solid blue;
  padding: 20px;
}
.error-message {
  border-color: red;
  color: red;
}
How @extend works
.box {
	   border: 1px solid blue;
	   padding: 20px;
}
.error-message {
	   @extend .box;
	   border-color: red;
	   color: red;
}




                              ⌘S
.box, .error-message {
  border: 1px solid blue;
  padding: 20px;
}
.error-message {
  border-color: red;
  color: red;
}
@extend Solution
.clearfix { zoom: 1; }
.clearfix:before, .clearfix:after { content: "0020"; display: block;...
.clearfix:after { clear: both; }

div {
	   @extend .clearfix;
}



                                  ⌘S

.clearfix, div { zoom: 1; }
.clearfix:before, div:before, .clearfix:after, div:after {...
.clearfix:after, div:after { clear: both; }
@extend more...
@import "_reset", "_grid", "_box";

div {
	   @extend .clearfix;
	   @extend .grid-12;
}

article {
	   @extend .box;
	   @extend .col-4;
}
Killer Feature #7
Skipping Technical Infos



gem install compass


   http://compass-style.org/install/
Compass is a
meta-framework
It helps you write
your own Framework
Boilerplate
Extensions
Good practices
It comes with
  2 frameworks


Core
Core


Design agnostic
Core
Provides mixins for

• CSS3 : no more vendor prefixes
• Typography : links, lists, text helpers
• Utilities : spriting the good way, others...
Core
Provides mixins for

• CSS3 : no more vendor prefixes
• Typography : links, lists, text helpers
• Utilities : spriting the good way, others...
CSS3 mixins
Border radius
div {
	   @include border-radius(5px);
}


                                   ⌘S
div {
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -khtml-border-radius: 5px;
    border-radius: 5px;
}
CSS3 mixins
Box Shadows
div {
	   @include box-shadow(rgba(black, 0.5) 0 2px 4px);
}


                                    ⌘S
div {
    -moz-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px;
    -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px;
    -o-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px;
    box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px;
}
CSS3 mixins
Gradients
div {
	   @include background(linear-gradient(top, red, green 50%, blue));
}


                                      ⌘S
div {
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%,
#ff0000), color-stop(50%, #008000), color-stop(100%, #0000ff));

    background:   -webkit-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
    background:   -moz-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
    background:   -o-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
    background:   -ms-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
    background:   linear-gradient(top, #ff0000, #008000 50%, #0000ff);
}
CSS3 mixins
Gradients
div {
	   @include background(linear-gradient(top, red, green 50%, blue));
}


                                      ⌘S
div {
  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%,
#ff0000), color-stop(50%, #008000), color-stop(100%, #0000ff));

    background:   -webkit-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
    background:   -moz-linear-gradient(top, #ff0000, #008000 50%, #0000ff);




}
    Solves inconsistency
    background:
    background:
    background:
                  -o-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
                  -ms-linear-gradient(top, #ff0000, #008000 50%, #0000ff);
                  linear-gradient(top, #ff0000, #008000 50%, #0000ff);
CSS3 mixins
Transforms
div {
	   @include rotate(20deg);
}


                                    ⌘S
div {
    -moz-transform: rotate(20deg);
    -webkit-transform: rotate(20deg);
    -o-transform: rotate(20deg);
    -ms-transform: rotate(20deg);
    transform: rotate(20deg);
}
More CSS3 mixins
background-clip
background-origin
background-size
box
box-sizing
columns
opacity
transform
transition
and more...
Spriting
Magic imports
@import "icons/*.png";
@include all-icons-sprites;
Spriting
Magic imports
@import "icons/*.png";
@include all-icons-sprites;




            ⌘S
.icons-sprite, .icons-tick, .icons-user, .icons-wrench {
  background: url('/img/icons-scc2e7acafa.png') no-repeat;
}
.icons-tick {
  background-position: 0 0;
}
.icons-user {
  background-position: 0 -16px;
}
.icons-wrench {
  background-position: 0 -32px;
}
Spriting
Magic imports
@import "icons/*.png";
@include all-icons-sprites;




            ⌘S
.icons-sprite, .icons-tick, .icons-user, .icons-wrench {
  background: url('/img/icons-scc2e7acafa.png') no-repeat;
}
.icons-tick {



                                                             +
  background-position: 0 0;
}
.icons-user {
  background-position: 0 -16px;
}
.icons-wrench {
  background-position: 0 -32px;
}
Spriting
Magic imports
@import "icons/*.png";
@include all-icons-sprites;




            ⌘S
.icons-sprite, .icons-tick, .icons-user, .icons-wrench {
  background: url('/img/icons-scc2e7acafa.png') no-repeat;
}
.icons-tick {



                                                             +
  background-position: 0 0;
}



       uses @extend
.icons-user {
  background-position: 0 -16px;
}
.icons-wrench {
  background-position: 0 -32px;
}
Spriting
Magic imports
@import "icons/*.png";
@include all-icons-sprites;

.icons-sprite {
	   width: 16px;
	   height: 16px;
}



            ⌘S
...

.icons-sprite, .icons-tick, .icons-user, .icons-wrench {
  width: 16px;
  height: 16px;
}
Fixing the Bad Parts
Variables                         Yep !

DRY                         Nesting & Mixins!

Modularity                      Imports !

Functions                         Yep !

Separation of Concerns    Mixins & Inheritance !

CSS3 vs.Vendor prefixing        Compass !
Bonus
Performance trick
Save HTTP Requests
Save HTTP Requests

  but don’t abuse
Include images
div {
	   background: url("icons/tick.png") no-repeat;
}
Include images
div {
	   background: inline-image("icons/tick.png") no-repeat;
}
Include images
div {
	   background: inline-image("icons/tick.png") no-repeat;
}



                                         ⌘S
base64 FTW !
div {
  background: url('data:image/
png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJl
YWR5ccllPAAAAhxJREFUeNpi/P//PwMlgImBQsACIhhnCAFZjEAGkANy0B8gwQ00m5kRogpEMYHl5YF4LZBXw/D3/47/Ea/
xuOD7PwaGX1AMMvDvfwGGf/8nprkkGQPZLUAVHqR4gY3hH0Ofoby+6ZcvXxjinWL0Gf4wtMC9QAAwAjXXK0jIO8gLyUl9/
Pzx98Fjh24AXdOA7gIPoP/PwJwGdvoPoNP/MGQIcwkGq4mrKHz5+uXf0UtH7wBdMRGodgvCgP9ATX/
+tyT5JxqCaDAfIu7DwcSWJckjqfzgwQOGU5dP3f3w4cNSoJq5DL//I0Xjn38tMX4xes+ePWOK8IowAPGBmnNZ/
jPVS4vLqH7985Xl5YcXDz99+rAJGIDtQAxxIcKA/zVLViy8xM7J9uvU7VPMDnaOOkAb4sVkxTV+sPxgf/fhzdOP797vZ/
gLjD4GBojObT8gAQRKiYx9/AxADaAwaDF2NtN6+vMZpwCnAMP7b
+8Zfrz49vrj3fdHGJgZkhhYmT4w7P4J1wzWCyY8OBgY5JiBmBFsiLSdvMYP3l/cv1/+/PD57Psz/5kYEhgO/
H4K1owEEAYwQlOcAtAQc2YPBmnGFi4TfpnvFz7d+f/wXyrD8T/
XGR79w4hfZANAYcELxAJAzMdgzGTJoMOQxnDmfyfD1f9XgGIgq39AaRD+xQDyNBDADAA5gR2IOaA0MzRX/IPiP1D8F4n
+BzeAEgAQYAC7HATaTnWSLQAAAABJRU5ErkJggg==') no-repeat;
}
Less HTTP Requests
       but
More Ko in your CSS
BTW...
Configuration
config.rb
# You can select your preferred output style here
output_style = :compressed



style.scss
div {
	     @include border-radius(5px);
	     @include box-shadow(rgba( black, 0.5) 0 2px 4px);
	     @include background(linear-gradient(top, red, green 50%, blue));
	     @include rotate(20deg);
}




                                               ⌘S
style.css minified
div{-moz-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-khtml-border-
radius:5px;border-radius:5px;-moz-box-shadow:rgba(0,0,0,0.5) 0 2px 4px;-webkit-box-shadow:rgba(0,0,0,0.5) 0 2px
4px;-o-box-shadow:rgba(0,0,0,0.5) 0 2px 4px;box-shadow:rgba(0,0,0,0.5) 0 2px 4px;background:-webkit-
gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(50%, #008000), color-stop(100%,
#0000ff));background:-webkit-linear-gradient(top, #ff0000,#008000 50%,#0000ff);background:-moz-linear-
gradient(top, #ff0000,#008000 50%,#0000ff);background:-o-linear-gradient(top, #ff0000,#008000
50%,#0000ff);background:-ms-linear-gradient(top, #ff0000,#008000 50%,#0000ff);background:linear-gradient(top,
.talk:after {
	 content: "Thanks";
}
More infos
http://sass-lang.com/
http://compass-style.org/
http://nex-3.com/
http://chriseppstein.github.com/
http://thesassway.com/

More Related Content

Similar to ParisJS #11 : Sass & Compass

SASS is more than LESS
SASS is more than LESSSASS is more than LESS
SASS is more than LESSItai Koren
 
CSS 開發加速指南-Sass & Compass
CSS 開發加速指南-Sass & CompassCSS 開發加速指南-Sass & Compass
CSS 開發加速指南-Sass & CompassLucien Lee
 
Pacific Northwest Drupal Summit: Basic & SASS
Pacific Northwest Drupal Summit: Basic & SASSPacific Northwest Drupal Summit: Basic & SASS
Pacific Northwest Drupal Summit: Basic & SASSSteve Krueger
 
Syntactically Awesome Stylesheet - A workshop by Citytech Software
Syntactically Awesome Stylesheet - A workshop by Citytech SoftwareSyntactically Awesome Stylesheet - A workshop by Citytech Software
Syntactically Awesome Stylesheet - A workshop by Citytech SoftwareRitwik Das
 
Intro to Sass for WordPress Developers
Intro to Sass for WordPress DevelopersIntro to Sass for WordPress Developers
Intro to Sass for WordPress DevelopersSuzette Franck
 
CSS előfeldolgozók
CSS előfeldolgozókCSS előfeldolgozók
CSS előfeldolgozókMáté Farkas
 
Deep dive into sass
Deep dive into sassDeep dive into sass
Deep dive into sassKnoldus Inc.
 
Simple introduction Sass
Simple introduction SassSimple introduction Sass
Simple introduction SassZeeshan Ahmed
 
Less(CSS Pre Processor) Introduction
Less(CSS Pre Processor) IntroductionLess(CSS Pre Processor) Introduction
Less(CSS Pre Processor) Introductionrushi7567
 
LESS(CSS Pre Processor) introduction
LESS(CSS Pre Processor) introductionLESS(CSS Pre Processor) introduction
LESS(CSS Pre Processor) introductionrushi7567
 
Sass that CSS
Sass that CSSSass that CSS
Sass that CSSTrish Ang
 
SCSS Implementation
SCSS ImplementationSCSS Implementation
SCSS ImplementationAmey Parab
 
Getting Sassy with CSS
Getting Sassy with CSSGetting Sassy with CSS
Getting Sassy with CSSJulie Cameron
 
Elegant CSS Design In Drupal: LESS vs Sass
Elegant CSS Design In Drupal: LESS vs SassElegant CSS Design In Drupal: LESS vs Sass
Elegant CSS Design In Drupal: LESS vs SassMediacurrent
 
Css preprocessor-140606115334-phpapp01
Css preprocessor-140606115334-phpapp01Css preprocessor-140606115334-phpapp01
Css preprocessor-140606115334-phpapp01Anam Hossain
 
CSS preprocessor: why and how
CSS preprocessor: why and howCSS preprocessor: why and how
CSS preprocessor: why and howmirahman
 
Using scss-at-noisestreet
Using scss-at-noisestreetUsing scss-at-noisestreet
Using scss-at-noisestreetWei Pin Teo
 

Similar to ParisJS #11 : Sass & Compass (20)

SASS is more than LESS
SASS is more than LESSSASS is more than LESS
SASS is more than LESS
 
CSS 開發加速指南-Sass & Compass
CSS 開發加速指南-Sass & CompassCSS 開發加速指南-Sass & Compass
CSS 開發加速指南-Sass & Compass
 
Crazy sassy
Crazy sassyCrazy sassy
Crazy sassy
 
Pacific Northwest Drupal Summit: Basic & SASS
Pacific Northwest Drupal Summit: Basic & SASSPacific Northwest Drupal Summit: Basic & SASS
Pacific Northwest Drupal Summit: Basic & SASS
 
Syntactically Awesome Stylesheet - A workshop by Citytech Software
Syntactically Awesome Stylesheet - A workshop by Citytech SoftwareSyntactically Awesome Stylesheet - A workshop by Citytech Software
Syntactically Awesome Stylesheet - A workshop by Citytech Software
 
Intro to Sass for WordPress Developers
Intro to Sass for WordPress DevelopersIntro to Sass for WordPress Developers
Intro to Sass for WordPress Developers
 
PostCss
PostCssPostCss
PostCss
 
CSS előfeldolgozók
CSS előfeldolgozókCSS előfeldolgozók
CSS előfeldolgozók
 
Deep dive into sass
Deep dive into sassDeep dive into sass
Deep dive into sass
 
Simple introduction Sass
Simple introduction SassSimple introduction Sass
Simple introduction Sass
 
Why less?
Why less?Why less?
Why less?
 
Less(CSS Pre Processor) Introduction
Less(CSS Pre Processor) IntroductionLess(CSS Pre Processor) Introduction
Less(CSS Pre Processor) Introduction
 
LESS(CSS Pre Processor) introduction
LESS(CSS Pre Processor) introductionLESS(CSS Pre Processor) introduction
LESS(CSS Pre Processor) introduction
 
Sass that CSS
Sass that CSSSass that CSS
Sass that CSS
 
SCSS Implementation
SCSS ImplementationSCSS Implementation
SCSS Implementation
 
Getting Sassy with CSS
Getting Sassy with CSSGetting Sassy with CSS
Getting Sassy with CSS
 
Elegant CSS Design In Drupal: LESS vs Sass
Elegant CSS Design In Drupal: LESS vs SassElegant CSS Design In Drupal: LESS vs Sass
Elegant CSS Design In Drupal: LESS vs Sass
 
Css preprocessor-140606115334-phpapp01
Css preprocessor-140606115334-phpapp01Css preprocessor-140606115334-phpapp01
Css preprocessor-140606115334-phpapp01
 
CSS preprocessor: why and how
CSS preprocessor: why and howCSS preprocessor: why and how
CSS preprocessor: why and how
 
Using scss-at-noisestreet
Using scss-at-noisestreetUsing scss-at-noisestreet
Using scss-at-noisestreet
 

Recently uploaded

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Recently uploaded (20)

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

ParisJS #11 : Sass & Compass

  • 2. Sass & http://sass-lang.com/ http://compass-style.org/
  • 3. Question #1 Do you write CSS ?
  • 4. Question #2 Do you love (writing) CSS ?
  • 5. Question #3 Did you love (writing) CSS ?
  • 6. Good News #1 Sass makes CSS fun again
  • 7. Good News #2 Sass will make you love CSS again
  • 8. Good News #3 Compass will make you love CSS3 again
  • 9. Who ? Julien Cabanès I care about Front End @ZeeAgency I reply to julien@zeeagency.com I tweet sometimes @JulienCabanes I share some code to github.com/ZeeAgency
  • 10. Things to remember today #1
  • 12. Save Your F... Keyboard !
  • 13. Save Your F... Keyboard !
  • 14. Things to remember today #2
  • 17. Think yourself as Indiana Jones...
  • 18. Think yourself as Indiana Jones... • You have to kill this son of a b... !
  • 19. Think yourself as Indiana Jones... • You have to kill this son of a b... ! • You have a gun.
  • 20. Think yourself as Indiana Jones... • You have to kill this son of a b... ! • You have a gun. • Why don’t you just ... use it ?
  • 21. Think yourself as Indiana Jones... • You have to style this website ! • You have a computer. • Why don’t you just ... use it ?
  • 22. End of the Story Back to the Code
  • 23. CSS : The Good Parts • CSS Syntax is easy • Selector Query Language is nice • Cascading is nice • Functions.Yes, CSS have functions • CSS2 : attr(), counter(), url() • CSS3 : calc(), translateX(), rotate()... • Media Queries • and more...
  • 24. CSS : The Bad Parts • Variables... come on ! (Still draft) • Selectors vs. DRY • Modularity : many files === many HTTP requests • Functions : Can’t write your owns • Separation of Concerns is almost impossible • CSS3 is great but vendors prefixing, damn ! • and more !
  • 27. Solution #2 Abstraction “ It’s nothing to be scared of ” - Chris Eppstein creator of Compass & Sass Core team member
  • 30. Good Abstraction Keep the Good Parts CSS is easy, Keep it easy
  • 31. Good Abstraction Keep the Good Parts Keep the Syntax
  • 33. Good Abstraction Forget the Bad Parts CSS is clearly not enough
  • 34. Good Abstraction Forget the Bad Parts Enhance the Syntax
  • 36. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Voluntary omitted of Other/PHP/Python CSS preprocessors (Turbine, CSS Cacheer...)
  • 37. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby
  • 38. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby
  • 39. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back
  • 40. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Front could be good way to go if this was a polyfill but CSS4 doesn’t exist yet
  • 41. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset
  • 42. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Your CSS won’t work
  • 43. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue;
  • 44. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset JS Like CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; traction bad abs
  • 45. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {}
  • 46. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} implicit abs traction co uld increase learni ng cur ve
  • 47. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} explicit ab s traction
  • 48. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} Import Style Style Style & Images !
  • 49. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} Import Style Style Style & Images !
  • 50. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} Import Style Style Style & Images ! Framework Roll your own Roll your own Compass
  • 51. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Written in JS JS Ruby Context Front & Local Local / Back Local / Back Syntax CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} Import Style Style Style & Images ! Framework Roll your own Roll your own Compass
  • 52. Quick Overview of CSS Pre-Processors LESS Stylus Sass/SCSS Run with JS JS Ruby Context Front & Local Local / Back Local / Back Syntax More on this later CSS Superset Not CSS CSS Superset Variable Syntax @color: blue; variable = blue $variable: blue; Mixins Syntax .foo() {} foo() @mixin foo() {} Import Style Style Style & Images ! Framework Roll your own Roll your own Compass
  • 53. Skipping Technical Infos gem install sass http://sass-lang.com/tutorial.html
  • 54. Sass • One language but 2 syntaxes • Sass : indented syntax, forget { } and ; • SCSS : Sassy CSS === CSS3 superset • Means Syntaxically Awesome StyleSheets • Should run on your machine, not the server • Is watching for folder/file changes and parse • Shares a lot of features with LESS & Stylus
  • 55. SCSS is a CSS3 Superset • Every existing CSS will work just fine ! • You love {...} and ; that’s OK ! • You want a little more ? Try it ! • You want a lot more ? Love it !
  • 58. Variables SCSS $link-color: #b4d455; a { color: $link-color; } ⌘S CSS a { color: #b4d455; }
  • 59. Variables Types // With or without unit $number: 1.2; $number: 10px; $number: 20%; // With or without quotes $string: "Hello World"; $string: '/img/icons.png'; $string: underline; // Any kind $color: #b4d455; $color: rgba(0, 0, 0, 0.5); $color: hsl(100deg, 40%, 60%); // Wow $boolean: true; $boolean: false; // With commas or spaces $list: 10px 5px 15px; $list: Helvetica, Arial, sans-serif;
  • 60. What can we do with Variables ?
  • 61. Number Operations Basic Arithmetic : + - * / % // Ever need this ? $lightbox-width: 500px; $lightbox-height: 400px; $lightbox-padding: 20px; .lightbox { position: absolute; top: 50%; ⌘S left: 50%; margin-top: -$lightbox-height / 2; margin-left: -$lightbox-width / 2; padding: $lightbox-padding; width: $lightbox-width - ($lightbox-padding * 2); height: $lightbox-height - ($lightbox-padding * 2); }
  • 62. Number Operations Talkin’ about division... // Division happens if.. variable, parentheses or other operation p { font: 10px / 8px; $width: 1000px; width: $width / 2; height: (500px / 2); margin-left: 5px + 8px / 2px; }
  • 63. Number Operations Talkin’ about division... // Division happens if.. variable, parentheses or other operation p { font: 10px / 8px; // Plain CSS, no division $width: 1000px; width: $width / 2; height: (500px / 2); margin-left: 5px + 8px / 2px; }
  • 64. Number Operations Talkin’ about division... // Division happens if.. variable, parentheses or other operation p { font: 10px / 8px; // Plain CSS, no division $width: 1000px; width: $width / 2; // Uses a variable, does division height: (500px / 2); margin-left: 5px + 8px / 2px; }
  • 65. Number Operations Talkin’ about division... // Division happens if.. variable, parentheses or other operation p { font: 10px / 8px; // Plain CSS, no division $width: 1000px; width: $width / 2; // Uses a variable, does division height: (500px / 2); // Uses parentheses, does division margin-left: 5px + 8px / 2px; }
  • 66. Number Operations Talkin’ about division... // Division happens if.. variable, parentheses or other operation p { font: 10px / 8px; // Plain CSS, no division $width: 1000px; width: $width / 2; // Uses a variable, does division height: (500px / 2); // Uses parentheses, does division margin-left: 5px + 8px / 2px; // Uses +, does division }
  • 67. Number Operations What about this ? p { $font-size: 10px; $line-height: 8px; font: $font-size / $line-height; }
  • 68. Number Operations What about this ? p { $font-size: 10px; $line-height: 8px; font: $font-size / $line-height; } ⌘S Ouch... p { font: 1.25; }
  • 69. Interpolation #{...} avoid operations p { $font-size: 10px; $line-height: 8px; font: #{$font-size} / #{$line-height}; }
  • 70. Interpolation #{...} avoid operations p { $font-size: 10px; $line-height: 8px; font: #{$font-size} / #{$line-height}; } ⌘S Nice p { font: 10px / 8px; }
  • 71. Interpolation #{...} can be used for... $className: 'foo'; $property: 'padding'; p.#{$className} { #{$property}: 10px; } ⌘S Templating ? p.foo { padding: 10px; }
  • 72. Color Operations Easy to understand p { color: #010203 + #040506; } a { color: #010203 * 2; } b { color: rgba(…) + rgba(…); } ⌘S p {color: #050709;} a {color: #020406;} b {color: rgba(…);}
  • 73. Number Functions Sounds familiar round(), ceil(), floor(), abs(), percentage() $width: 960px; $columns: 14; div { width: round($width / $columns); } ⌘S div { width: 69px; }
  • 74. Color Functions Lazy RGBA, yay ! $my-color: rgba(#b4d455, 0.5); Mutators $my-color: mix(red, blue); $my-color: lighten(red, 20%); $my-color: darken(red, 20%); $my-color: transparentize($my-color, 0.5); $my-color: opacify($my-color, 0.5); $my-color: grayscale(#b4d455); $my-color: invert(#b4d455); $my-color: saturate(#b4d455, 10%); $my-color: adjust-hue(#b4d455, 10%); // And more…
  • 75. Color Functions Getters (aka Accessors) $red-component: red($my-color); $green-component: green($my-color); $blue-component: blue($my-color); $alpha-component: alpha($my-color); $hue-component: hue($my-color); $sat-component: saturation($my-color); $light-component: lightness($my-color); Setters $my-color: adjust-color($my-color, $green: -55); $my-color: scale-color($my-color, $green: 10%); $my-color: change-color($my-color, $green: 255);
  • 78. Nesting Properties article { background: { color: transparent; image: url("/img/bg.png"); origin: content-box; position: right center; repeat: no-repeat; size: 100px 100px; } } ⌘S article { background-color: transparent; background-image: url("/img/bg.png"); background-origin: content-box; background-position: right center; background-repeat: no-repeat; background-size: 100px 100px; }
  • 79. Nesting Rules h1 { font-size: 200%; a { text-decoration: none; &:hover { text-decoration: underline; } } } ⌘S h1 {font-size: 200%;} h1 a {text-decoration: none;} h1 a:hover {text-decoration: underline;}
  • 80. Nesting Rules h1 { font-size: 200%; & means this a { text-decoration: none; &:hover { text-decoration: underline; } } } ⌘S h1 {font-size: 200%;} h1 a {text-decoration: none;} h1 a:hover {text-decoration: underline;}
  • 81. Warning Rules Nesting helps you write more typing less
  • 82. Warning Rules Nesting helps you write more typing less
  • 85. Warning Selectors doesn’t need to reflect your DOM...
  • 86. Nesting abuse #wrapper { section { article { h2 { font-size: 200%; a { color: red; &:hover { text-decoration: underline; } } } p { text-align: justify; } } } }
  • 87. Control Directives @if @else @for @each @while Trivial @if 1 + 1 == 2 { width: 400px; } @else { width: 200px; } Grids @for $i from 1 through 10 { .col-#{$i} { width: $i * 10px; } }
  • 92. Don’t use @import Use @import !
  • 94. @import reset.scss html, body, div, span, object, iframe, style.scss h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr... @import "reset", "header"; header.scss ⌘S header { height: 100px; font-size: 200%; } style.css html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr... ... ... ... header { height: 100px; font-size: 200%; }
  • 95. Make your own Abstractions
  • 97. Functions Define with @function @function round-by($value, $factor: 1) { @return round($value / $factor) * $factor; } div { width: round-by(1337px, 20); } ⌘S div { width: 1340px; }
  • 99. Mixins Define with @mixin, use with @include @mixin link-hover-effect($color) { color: $color; &:hover { color: darken($color, 10%); } } article a { @include link-hover-effect( blue); } ⌘S article a { color: blue; } article a:hover { color: #0000cc; }
  • 101. Pause
  • 102. Fixing the Bad Parts Variables DRY Modularity Functions Separation of Concerns CSS3 vs.Vendor prefixing
  • 103. Fixing the Bad Parts Variables Yep ! DRY Modularity Functions Separation of Concerns CSS3 vs.Vendor prefixing
  • 104. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Functions Separation of Concerns CSS3 vs.Vendor prefixing
  • 105. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Imports ! Functions Separation of Concerns CSS3 vs.Vendor prefixing
  • 106. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Imports ! Functions Yep ! Separation of Concerns CSS3 vs.Vendor prefixing
  • 107. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Imports ! Functions Yep ! Separation of Concerns ? CSS3 vs.Vendor prefixing ?
  • 108. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Imports ! Functions Yep ! Separation of Concerns Mixins ? CSS3 vs.Vendor prefixing ?
  • 109. Separation of Concerns Clearfix example <div class="clearfix"> <article>Lorem ipsum</article> <article>Lorem ipsum</article> <article>Lorem ipsum</article> </div> <div class="clearfix"> <article>Lorem ipsum</article> <article>Lorem ipsum</article> <article>Lorem ipsum</article> </div>
  • 110. Separation of Concerns Clearfix example <div> <article>Lorem ipsum</article> <article>Lorem ipsum</article> <article>Lorem ipsum</article> </div> <div> <article>Lorem ipsum</article> <article>Lorem ipsum</article> <article>Lorem ipsum</article> </div>
  • 111. @mixin Solution @mixin clearfix { zoom: 1; &:before, &:after { content: "0020"; display: block; height: 0; visibility: hidden; } &:after { clear: both; } } div { @include clearfix; }
  • 112. @mixin Solution @mixin clearfix { zoom: 1; &:before, &:after { content: "0020"; display: block; height: 0; visibility: hidden; } &:after { clear: both; } } div { @include clearfix; }
  • 113. @mixin Solution Style will be repeated for every mixin uses div { zoom: 1; } div:before, div:after { content: "0020"; ⌘S display: block; height: 0; visibility: hidden; } div:after { clear: both; }
  • 114. @mixin Solution Style will be repeated for every mixin uses div { zoom: 1; } div:before, div:after { content: "0020"; ⌘S display: block; height: 0; visibility: hidden; } div:after { clear: both; } There’s a better way...
  • 116. Inheritance @extend is at selectors what @mixin is for styles
  • 117. How @extend works .box { border: 1px solid blue; padding: 20px; } .error-message { @extend .box; border-color: red; color: red; } ⌘S .box, .error-message { border: 1px solid blue; padding: 20px; } .error-message { border-color: red; color: red; }
  • 118. How @extend works .box { border: 1px solid blue; padding: 20px; } .error-message { @extend .box; border-color: red; color: red; } ⌘S .box, .error-message { border: 1px solid blue; padding: 20px; } .error-message { border-color: red; color: red; }
  • 119. @extend Solution .clearfix { zoom: 1; } .clearfix:before, .clearfix:after { content: "0020"; display: block;... .clearfix:after { clear: both; } div { @extend .clearfix; } ⌘S .clearfix, div { zoom: 1; } .clearfix:before, div:before, .clearfix:after, div:after {... .clearfix:after, div:after { clear: both; }
  • 120. @extend more... @import "_reset", "_grid", "_box"; div { @extend .clearfix; @extend .grid-12; } article { @extend .box; @extend .col-4; }
  • 122.
  • 123. Skipping Technical Infos gem install compass http://compass-style.org/install/
  • 125. It helps you write your own Framework
  • 129. It comes with 2 frameworks Core
  • 131. Core Provides mixins for • CSS3 : no more vendor prefixes • Typography : links, lists, text helpers • Utilities : spriting the good way, others...
  • 132. Core Provides mixins for • CSS3 : no more vendor prefixes • Typography : links, lists, text helpers • Utilities : spriting the good way, others...
  • 133. CSS3 mixins Border radius div { @include border-radius(5px); } ⌘S div { -moz-border-radius: 5px; -webkit-border-radius: 5px; -o-border-radius: 5px; -ms-border-radius: 5px; -khtml-border-radius: 5px; border-radius: 5px; }
  • 134. CSS3 mixins Box Shadows div { @include box-shadow(rgba(black, 0.5) 0 2px 4px); } ⌘S div { -moz-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px; -webkit-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px; -o-box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px; box-shadow: rgba(0, 0, 0, 0.5) 0 2px 4px; }
  • 135. CSS3 mixins Gradients div { @include background(linear-gradient(top, red, green 50%, blue)); } ⌘S div { background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(50%, #008000), color-stop(100%, #0000ff)); background: -webkit-linear-gradient(top, #ff0000, #008000 50%, #0000ff); background: -moz-linear-gradient(top, #ff0000, #008000 50%, #0000ff); background: -o-linear-gradient(top, #ff0000, #008000 50%, #0000ff); background: -ms-linear-gradient(top, #ff0000, #008000 50%, #0000ff); background: linear-gradient(top, #ff0000, #008000 50%, #0000ff); }
  • 136. CSS3 mixins Gradients div { @include background(linear-gradient(top, red, green 50%, blue)); } ⌘S div { background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(50%, #008000), color-stop(100%, #0000ff)); background: -webkit-linear-gradient(top, #ff0000, #008000 50%, #0000ff); background: -moz-linear-gradient(top, #ff0000, #008000 50%, #0000ff); } Solves inconsistency background: background: background: -o-linear-gradient(top, #ff0000, #008000 50%, #0000ff); -ms-linear-gradient(top, #ff0000, #008000 50%, #0000ff); linear-gradient(top, #ff0000, #008000 50%, #0000ff);
  • 137. CSS3 mixins Transforms div { @include rotate(20deg); } ⌘S div { -moz-transform: rotate(20deg); -webkit-transform: rotate(20deg); -o-transform: rotate(20deg); -ms-transform: rotate(20deg); transform: rotate(20deg); }
  • 140. Spriting Magic imports @import "icons/*.png"; @include all-icons-sprites; ⌘S .icons-sprite, .icons-tick, .icons-user, .icons-wrench { background: url('/img/icons-scc2e7acafa.png') no-repeat; } .icons-tick { background-position: 0 0; } .icons-user { background-position: 0 -16px; } .icons-wrench { background-position: 0 -32px; }
  • 141. Spriting Magic imports @import "icons/*.png"; @include all-icons-sprites; ⌘S .icons-sprite, .icons-tick, .icons-user, .icons-wrench { background: url('/img/icons-scc2e7acafa.png') no-repeat; } .icons-tick { + background-position: 0 0; } .icons-user { background-position: 0 -16px; } .icons-wrench { background-position: 0 -32px; }
  • 142. Spriting Magic imports @import "icons/*.png"; @include all-icons-sprites; ⌘S .icons-sprite, .icons-tick, .icons-user, .icons-wrench { background: url('/img/icons-scc2e7acafa.png') no-repeat; } .icons-tick { + background-position: 0 0; } uses @extend .icons-user { background-position: 0 -16px; } .icons-wrench { background-position: 0 -32px; }
  • 143. Spriting Magic imports @import "icons/*.png"; @include all-icons-sprites; .icons-sprite { width: 16px; height: 16px; } ⌘S ... .icons-sprite, .icons-tick, .icons-user, .icons-wrench { width: 16px; height: 16px; }
  • 144. Fixing the Bad Parts Variables Yep ! DRY Nesting & Mixins! Modularity Imports ! Functions Yep ! Separation of Concerns Mixins & Inheritance ! CSS3 vs.Vendor prefixing Compass !
  • 145. Bonus
  • 148. Save HTTP Requests but don’t abuse
  • 149. Include images div { background: url("icons/tick.png") no-repeat; }
  • 150. Include images div { background: inline-image("icons/tick.png") no-repeat; }
  • 151. Include images div { background: inline-image("icons/tick.png") no-repeat; } ⌘S base64 FTW ! div { background: url('data:image/ png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJl YWR5ccllPAAAAhxJREFUeNpi/P//PwMlgImBQsACIhhnCAFZjEAGkANy0B8gwQ00m5kRogpEMYHl5YF4LZBXw/D3/47/Ea/ xuOD7PwaGX1AMMvDvfwGGf/8nprkkGQPZLUAVHqR4gY3hH0Ofoby+6ZcvXxjinWL0Gf4wtMC9QAAwAjXXK0jIO8gLyUl9/ Pzx98Fjh24AXdOA7gIPoP/PwJwGdvoPoNP/MGQIcwkGq4mrKHz5+uXf0UtH7wBdMRGodgvCgP9ATX/ +tyT5JxqCaDAfIu7DwcSWJckjqfzgwQOGU5dP3f3w4cNSoJq5DL//I0Xjn38tMX4xes+ePWOK8IowAPGBmnNZ/ jPVS4vLqH7985Xl5YcXDz99+rAJGIDtQAxxIcKA/zVLViy8xM7J9uvU7VPMDnaOOkAb4sVkxTV+sPxgf/fhzdOP797vZ/ gLjD4GBojObT8gAQRKiYx9/AxADaAwaDF2NtN6+vMZpwCnAMP7b +8Zfrz49vrj3fdHGJgZkhhYmT4w7P4J1wzWCyY8OBgY5JiBmBFsiLSdvMYP3l/cv1/+/PD57Psz/5kYEhgO/ H4K1owEEAYwQlOcAtAQc2YPBmnGFi4TfpnvFz7d+f/wXyrD8T/ XGR79w4hfZANAYcELxAJAzMdgzGTJoMOQxnDmfyfD1f9XgGIgq39AaRD+xQDyNBDADAA5gR2IOaA0MzRX/IPiP1D8F4n +BzeAEgAQYAC7HATaTnWSLQAAAABJRU5ErkJggg==') no-repeat; }
  • 152. Less HTTP Requests but More Ko in your CSS
  • 153. BTW...
  • 154. Configuration config.rb # You can select your preferred output style here output_style = :compressed style.scss div { @include border-radius(5px); @include box-shadow(rgba( black, 0.5) 0 2px 4px); @include background(linear-gradient(top, red, green 50%, blue)); @include rotate(20deg); } ⌘S style.css minified div{-moz-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;-ms-border-radius:5px;-khtml-border- radius:5px;border-radius:5px;-moz-box-shadow:rgba(0,0,0,0.5) 0 2px 4px;-webkit-box-shadow:rgba(0,0,0,0.5) 0 2px 4px;-o-box-shadow:rgba(0,0,0,0.5) 0 2px 4px;box-shadow:rgba(0,0,0,0.5) 0 2px 4px;background:-webkit- gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0000), color-stop(50%, #008000), color-stop(100%, #0000ff));background:-webkit-linear-gradient(top, #ff0000,#008000 50%,#0000ff);background:-moz-linear- gradient(top, #ff0000,#008000 50%,#0000ff);background:-o-linear-gradient(top, #ff0000,#008000 50%,#0000ff);background:-ms-linear-gradient(top, #ff0000,#008000 50%,#0000ff);background:linear-gradient(top,
  • 155. .talk:after { content: "Thanks"; }