Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How LESS and Sass will change your life!

Avatar for rhuk rhuk
November 09, 2013

How LESS and Sass will change your life!

Presentation I did about LESS and Sass preprocessors for the 2013 Joomla World Conference in Boston, MA

Avatar for rhuk

rhuk

November 09, 2013
Tweet

Other Decks in Programming

Transcript

  1. @rhuk #JWC13_DESIGN –Wikipedia “Cascading Style Sheets is a style sheet

    language used for describing the presentation semantics of a document written in a markup language.”
  2. @rhuk #JWC13_DESIGN WHAT ARE CSS PREPROCESSORS? • Provides additional features

    over CSS3 • Generally extend familiar CSS syntax • Compiles into valid CSS syntax • Many options including LESS, Sass, Stylus, Turbine, Switch CSS + more!
  3. @rhuk #JWC13_DESIGN WHY NOT JUST USE CSS? • Cleaner DRYer

    Code with Mixins • Better organization with Nesting • Easier maintenance with Variables • More flexible coding with Math and Operations
  4. @rhuk #JWC13_DESIGN LESS was originally built as a JavaScript library

    by Alexis Sellier in 2009. ! LESS compiles .less files at runtime and sends back CSS to the browser with the JS Script option, or can be done by developer using the Node.js version.
  5. @rhuk #JWC13_DESIGN Sass was originally developed as a Ruby application

    by Hampton Catlin in 2007. ! Sass compiles .sass files into .css. As of SASS 3, Sassy CSS or .scss files are the preferred format as it extends CSS syntax making any valid CSS file a valid Sass file.
  6. @rhuk #JWC13_DESIGN • Similar syntax based on CSS3 • Nesting

    • Variables • Mixins / functions • Color transformations • Math operations • DRY Principals • Quiet comments • Vendor prefix handling +
  7. @rhuk #JWC13_DESIGN DIFFERENTIATORS • Namespaces • More mature/stable • Better

    website with cleaner docs • Used in Bootstrap! • Guarded mixins • ummm… let’s move on!
  8. @rhuk #JWC13_DESIGN DIFFERENTIATORS • Loops & Conditionals • @extend, @media,

    @content • Inheritance • Scoped variables • %placeholders • Better error reporting • Source Maps!
  9. @rhuk #JWC13_DESIGN INSTALLATION 1. Download LESS from http://lesscss.org 2. Link

    your .less stylesheets with <link />
 
 3. Link your less.js file in a <script /> tag <link rel="stylesheet/less" type="text/css" href="styles.less" /> ! <script src="less.js" type="text/javascript"></script>
  10. @rhuk #JWC13_DESIGN INSTALLATION 1. Install Ruby if required (Macs has

    it built-in) 2. Install Sass with it’s Ruby Gem
 
 3. Run Sass with .scss source and .css output dirs $ sudo gem install sass ! $ sass —-watch path/scss-directory:path/css-directory
  11. @rhuk #JWC13_DESIGN GUI APPLICATIONS There are many GUI applications that

    automatically watch and compile your LESS or Sass source files into CSS. ! They often also provide powerful features such as compression, JSLint, image optimization and live browser reloading
  12. @rhuk #JWC13_DESIGN GETTING DIRTY! • Nesting • Variables • Mixins

    / Functions • Importing • Color Functions • Operations / Math • Commenting • Conditionals & Looping • Inheritance via @extend
  13. @rhuk #JWC13_DESIGN body { h1 { color: #333333; } a

    { color: #5581B5; text-decoration: none; &:hover { text-decoration: underline; } } ul { > li { font-weight: bold; } } } body h1 { color: #333333; } body a { color: #5581B5; text-decoration: none; } body a:hover { text-decoration: underline; } body ul > li { font-weight: bold; } NESTING CSS
  14. @rhuk #JWC13_DESIGN VARIABLES /* Variables */ @base-font-family: "HelveticaNeue-Light", Helvetica, Arial;

    @base-font-weight: 300; @body-font-color: #B5558A; ! /* Base Setup */ body { font-family: @base-font-family; font-weight: @base-font-weight; color: @body-font-color; } /* Variables */ $base-font-family: "HelveticaNeue-Light", Helvetica, Arial; $base-font-weight: 300; $body-font-color: #B5558A; ! /* Base Setup */ body { font-family: $base-font-family; font-weight: $base-font-weight; color: $body-font-color; }
  15. @rhuk #JWC13_DESIGN MIXINS /* Mixin */ .bordered { border-top: dotted

    1px black; border-bottom: solid 2px black; } ! #menu a { color: blue; .bordered; } ! /* Mixin with Arguments */ .sexy-border(@color, @width) { border-color: @color; border-width: @width; border-style: dashed; } ! p { .sexy-border(blue, 10px); }
  16. @rhuk #JWC13_DESIGN MIXINS /* Mixin */ @mixin bordered { border-top:

    dotted 1px black; border-bottom: solid 2px black; } ! #menu a { color: blue; @include bordered; } ! /* Mixin with Arguments */ @mixin sexy-border($color, $width) { border: { color: $color; width: $width; style: dashed; } } ! p { @include sexy-border(blue, 10px); }
  17. @rhuk #JWC13_DESIGN MIXINS /* Mixin */ #menu a { color:

    blue; border-top: dotted 1px black; border-bottom: solid 2px black; } ! /* Mixin with Arguments */ p { border-color: blue; border-width: 10px; border-style: dashed; } CSS
  18. @rhuk #JWC13_DESIGN @IMPORT /* library.less */ @imported-color: red; h1 {

    color: green; } /* Test @import */ pre { @import "library.less"; color: @imported-color; } /* Output */ pre { color: red; } ! pre h1 { color: green; } CSS
  19. @rhuk #JWC13_DESIGN @IMPORT /* library.less */ $imported-color: red; h1 {

    color: green; } /* Test @import */ pre { @import "library"; color: $imported-color; } /* Output */ pre { color: red; } ! pre h1 { color: green; } CSS
  20. @rhuk #JWC13_DESIGN COLOR FUNCTIONS saturate(@color, 10%); // return a color

    10% points *more* saturated desaturate(@color, 10%); // return a color 10% points *less* saturated lighten(@color, 10%); // return a color 10% points *lighter* darken(@color, 10%); // return a color 10% points *darker* fadein(@color, 10%); // return a color 10% points *less* transparent fadeout(@color, 10%); // return a color 10% points *more* transparent fade(@color, 50%); // return @color with 50% transparency spin(@color, 10); // return a color with a 10 degree larger in hue tint(@color, 10%); // return a color mixed 10% with white shade(@color, 10%); // return a color mixed 10% with black greyscale(@color); // returns a grey, 100% desaturated color contrast(@color1, [@darkcolor: black], [@lightcolor: white], [@threshold: 43%]); // return @darkcolor if @color1 is > 43% luma // otherwise return @lightcolor, see notes !
  21. @rhuk #JWC13_DESIGN COLOR FUNCTIONS saturate($color, 10%); // return a color

    10% points *more* saturated desaturate($color, 10%); // return a color 10% points *less* saturated lighten($color, 10%); // return a color 10% points *lighter* darken($color, 10%); // return a color 10% points *darker* opacify($color, 10%); // return a color 10% points *less* transparent transparentize($color, 10%); // return a color 10% points *more* transparent change-color($color, $alpha: 0.5); // return $color with 50% transparency *1 adjust-hue($color, 10deg); // return a color with a 10 degree larger in hue tint($color, 10%); // return a color mixed 10% with white shade($color, 10%); // return a color mixed 10% with black grayscale($color); // returns a gray, 100% desaturated color text-contrast($color1); // returns contrasted color *2 ! *1 : Requires Bourbon mixin *2 : Requires 3rd party mixin
  22. @rhuk #JWC13_DESIGN MATH OPERATIONS /* Math in Less supports +,

    -, *, /, and % */ @grid: 960px; @offset: 15px; .container { width: 100%; } ! article[role="main"] { float: left; width: (600px - @offset) / @grid * 100%; } ! aside[role="complimentary"] { float: right; width: (300px + @offset) / @grid * 100%; } .container { width: 100%; } ! article[role="main"] { float: left; width: 60.9375%; } ! aside[role="complimentary"] { float: right; width: 32.8125%; } CSS
  23. @rhuk #JWC13_DESIGN /* Math in Sass supports +, -, *,

    /, and % */ $grid: 960px; $offset: 15px; .container { width: 100%; } ! article[role="main"] { float: left; width: (600px - $offset) / $grid * 100%; } ! aside[role="complimentary"] { float: right; width: (300px + $offset) / $grid * 100%; } MATH OPERATIONS .container { width: 100%; } ! article[role="main"] { float: left; width: 60.9375%; } ! aside[role="complimentary"] { float: right; width: 32.8125%; } CSS
  24. @rhuk #JWC13_DESIGN /* This comment is * several lines long.

    * since it uses the CSS comment syntax, * it will appear in the CSS output. */ body { color: black; } ! // These comments are only one line long each. // They won't appear in the CSS output, // since they use the single-line comment syntax. a { color: green; } /* This comment is * several lines long. * since it uses the CSS comment syntax, * it will appear in the CSS output. */ body { color: black; } ! a { color: green; } COMMENTING CSS
  25. @rhuk #JWC13_DESIGN /* Guarded Mixins */ .boxguard(@color) when (lightness(@color) >

    50%) { border: 1px solid red; } .boxguard(@color) when (lightness(@color) == 50%) { border: 1px solid green; } .boxguard(@color) when (lightness(@color) < 50%) { border: 1px solid blue; } // Usage .mydiv { .boxguard(#5581B5); } .mydiv { border: 1px solid red; } GUARDED MIXINS CSS
  26. @rhuk #JWC13_DESIGN @mixin boxguard($color) { @if lightness($color) >= 50 {

    border: 1px solid red; } @else if lightness($color == 50) { border: 1px solid green; } @else { border: 1px solid blue; } } ! .mydiv { @include boxguard(#5581b5); } .mydiv { border: 1px solid red; } @IF STATEMENT CSS
  27. @rhuk #JWC13_DESIGN @for $i from 1 through 3 { .item-#{$i}

    { width: 2em * $i; } } .item-1 { width: 2em; } ! .item-2 { width: 4em; } ! .item-3 { width: 6em; } @FOR LOOP CSS
  28. @rhuk #JWC13_DESIGN @each $animal in puma, sea-slug, egret, salamander {

    .#{$animal}-icon { background-image: url('/images/#{$animal}.png'); } } .puma-icon { background-image: url("/images/puma.png"); } ! .sea-slug-icon { background-image: url("/images/sea-slug.png"); } ! .egret-icon { background-image: url("/images/egret.png"); } ! .salamander-icon { background-image: url("/images/salamander.png"); } @EACH LOOP CSS
  29. @rhuk #JWC13_DESIGN $i: 6; @while $i > 0 { .item-#{$i}

    { width: 2em * $i; } $i: $i - 2; } .item-6 { width: 12em; } ! .item-4 { width: 8em; } ! .item-2 { width: 4em; } @WHILE LOOP CSS
  30. @rhuk #JWC13_DESIGN @mixin border-style { border: 1px solid #ccc; padding:

    10px; border-radius: 6px; } ! .foo { @include border-style; } ! .bar { @include border-style; } .foo { border: 1px solid #ccc; padding: 10px; border-radius: 6px; } ! .bar { border: 1px solid #ccc; padding: 10px; border-radius: 6px; } MIXIN CLASS-ITIS CSS
  31. @rhuk #JWC13_DESIGN .border-box { border: 1px solid #ccc; } !

    .blue-bordered { @extend .border-box; border-color: blue; } ! .red-bordered { @extend .border-box; border-color: red; } .border-box, .blue-bordered, .red-bordered { border: 1px solid #ccc; } ! .blue-bordered { border-color: blue; } ! .red-bordered { border-color: red; } @EXTEND CSS
  32. @rhuk #JWC13_DESIGN %border-style { border: 1px solid #ccc; padding: 10px;

    border-radius: 6px; } ! .foo { @extend %border-style; } ! .bar { @extend %border-style; } .foo, .bar { border: 1px solid #ccc; padding: 10px; border-radius: 6px; } @EXTEND AND % CSS
  33. @rhuk #JWC13_DESIGN $color: white; @mixin colors($color: blue) { background-color: $color;

    @content; border-color: $color; } .colors { @include colors { color: $color; } } .colors { background-color: blue; color: white; border-color: blue; } @CONTENT + SCOPE CSS
  34. @rhuk #JWC13_DESIGN $break-small: 320px; $break-large: 1024px; ! @mixin respond-to($media) {

    @if $media == handhelds { @media only screen and (max-width: $break-small) { @content; } } @else if $media == medium-screens { @media only screen and (min-width: $break-small + 1) and (max-width: $break-large - 1) { @content; } } @else if $media == wide-screens { @media only screen and (min-width: $break-large) { @content; } } } ! .profile-pic { float: left; width: 250px; @include respond-to(handhelds) { width: 100% ;} @include respond-to(medium-screens) { width: 125px; } @include respond-to(wide-screens) { float: none; } } @MEDIA
  35. @rhuk #JWC13_DESIGN .profile-pic { float: left; width: 250px; } !

    @media only screen and (max-width: 320px) { .profile-pic { width: 100%; } } @media only screen and (min-width: 321px) and (max-width: 1023px) { .profile-pic { width: 125px; } } @media only screen and (min-width: 1024px) { .profile-pic { float: none; } } @MEDIA CSS
  36. @rhuk #JWC13_DESIGN GOTCHAS • Extra step in development process (Sass)


    Learn to love the CLI, or use a GUI • Performance implication of JavaScript LESS
 Use Node.js version • Watching for Class-itis and Nesting Jungle
 Be smart about nesting-depth, use @extend and % • Disconnect between source and compiled CSS
 Sass supports sourcemaps, maybe LESS will in the future?
  37. @rhuk #JWC13_DESIGN SOURCE MAPS 1. Install Sass 3.3+
 
 2.

    Run Sass with source maps + watch
 
 3. Verify Sass is generating output.css.map files for each .css file $ sudo gem install sass -v ‘>=3.3.0alpha' —-pre $ sass —-sourcemap —-watch scss:css
  38. @rhuk #JWC13_DESIGN RESOURCES • http://lesscss.org - Homepage • http://lesselements.com -

    Essential Mixins • http://lesshat.com - Extensive Mixin Collection • http://getbootstrap.com - LESS Framework • https://github.com/danro/LESS-sublime
  39. @rhuk #JWC13_DESIGN RESOURCES • http://sass-lang.com - Homepage • http://thesassway.com/ -

    Great tutorials • http://compass-style.org - Powerful framework • http://bourbon.io - Lightweight Mixin Collection • http://foundation.zurb.com - Sass Framework • https://github.com/adamstac/animate.sass • http://jaredhardy.com/sassy-buttons • https://github.com/danro/SCSS-sublime