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

Automate All The Things: Sass, Haml, CoffeeScript

Automate All The Things: Sass, Haml, CoffeeScript

Learn how to write beautiful markup with Haml, faster CSS with Sass, and better JavaScript with CoffeeScript. We'll walk through the benefits of these compilers and learn how you can incorporate them in your project. Intended for anyone interested in more expedient tools.

This talk was given at the fall HTML5DevConf in San Francisco.

Christopher Webb

October 15, 2012
Tweet

More Decks by Christopher Webb

Other Decks in Technology

Transcript

  1. // .sass $brand-color: #6DAB62 h1, h2, h3, h4, h5, h6

    color: $brand-color .widget border: 2px solid $brand-color
  2. /* .css */ h1, h2, h3, h4, h5, h6 {

    color: #6DAB62; } .widget { border: 2px solid #6DAB62; }
  3. // .sass $brand-color: #6DAB62 h1, h2, h3, h4, h5, h6

    color: $brand-color .widget border: 2px solid $brand-color /* .css */ h1, h2, h3, h4, h5, h6 { color: #6DAB62; } .widget { border: 2px solid #6DAB62; }
  4. // .sass $modal-width: 400px .modal left: 50% margin-left: -($modal-width/2) position:

    absolute top: 100px width: $modal-width /* .css */ .modal { left: 50%; margin-left: -200px; position: absolute; top: 100px; width: 400px; }
  5. // .sass p font: family: sans-serif size: 16px weight: bold

    margin: top: 20px right: 0 bottom: 10px left: 15px
  6. /* .css */ p { font-family: sans-serif; font-size: 16px; font-weight:

    bold; margin-top: 20px; margin-right: 0; margin-bottom: 10px; margin-left: 15px; }
  7. // .sass p font: family: sans-serif size: 16px weight: bold

    margin: top: 20px right: 0 bottom: 10px left: 15px /* .css */ p { font-family: sans-serif; font-size: 16px; font-weight: bold; margin-top: 20px; margin-right: 0; margin-bottom: 10px; margin-left: 15px; }
  8. // .sass ul margin-left: 0 list-style: none li float: left

    margin-right: 10px a color: green text-decoration: none
  9. /* .css */ ul { margin-left: 0; list-style: none; }

    ul li { float: left; margin-right: 10px; } ul li a { color: green; text-decoration: none; }
  10. // .sass ul margin-left: 0 list-style: none li float: left

    margin-right: 10px a color: green text-decoration: none /* .css */ ul { margin-left: 0; list-style: none; } ul li { float: left; margin-right: 10px; } ul li a { color: green; text-decoration: none; }
  11. // .sass a color: green text-decoration: none &:hover text-decoration: underline

    &:active color: blue .lt-ie9 & color: red font-weight: bold
  12. /* .css */ a { color: green; text-decoration: none; }

    a:hover { text-decoration: underline; } a:active { color: blue; } .lt-ie9 a { color: red; font-weight: bold; }
  13. // .sass a color: green text-decoration: none &:hover text-decoration: underline

    &:active color: blue .lt-ie9 & color: red font-weight: bold /* .css */ a { color: green; text-decoration: none; } a:hover { text-decoration: underline; } a:active { color: blue; } .lt-ie9 a { color: red; font-weight: bold; }
  14. // .sass =linkify($color: red, $highlight: blue) color: $color &:hover color:

    $highlight a +linkify nav a +linkify(green, purple)
  15. /* .css */ a { color: red; } a:hover {

    color: blue; } nav a { color: green; } nav a:hover { color: purple; }
  16. // .sass =linkify($color: red, $highlight: blue) color: $color &:hover color:

    $highlight a +linkify nav a +linkify(green, purple) /* .css */ a { color: red; } a:hover { color: blue; } nav a { color: green; } nav a:hover { color: purple; }
  17. // .sass $season: fall body @if $season == spring background:

    green color: pink @else if $season == summer background: lightblue color: yellow @else if $season == fall background: brown color: orange @else if $season == winter background: white color: green
  18. // .sass $season: fall body @if $season == spring background:

    green color: pink @else if $season == summer background: lightblue color: yellow @else if $season == fall background: brown color: orange @else if $season == winter background: white color: green /* .css */ body { background: brown; color: orange; }
  19. // .sass @each $brand in nike, hyatt, ford, budweiser .#{$brand}-logo

    background-image: url('/images/brands/ #{$brand).jpg') no-repeat
  20. /* .css */ .nike-logo { background-image: url(‘/images/brands/nike.jpg’) no-repeat; } .hyatt-logo

    { background-image: url(‘/images/brands/hyatt.jpg’) no-repeat; } .ford-logo { background-image: url(‘/images/brands/ford.jpg’) no-repeat; } .budweiser-logo { background-image: url(‘/images/brands/ budweiser.jpg’) no-repeat; }
  21. // .sass @each $brand in nike, hyatt, ford, budweiser .#{$brand}-logo

    backround-image: url('/ images/brands/#{$brand).jpg') no-repeat /* .css */ .nike-logo { background-image: url(‘/ images/brands/nike.jpg’) no- repeat; } .hyatt-logo { background-image: url(‘/ images/brands/hyatt.jpg’) no- repeat; } .ford-logo { background-image: url(‘/ images/brands/ford.jpg’) no- repeat; } .budweiser-logo { background-image: url(‘/ images/brands/budweiser.jpg’) no-repeat; }
  22. // .sass $gutterWidth: 5px $totalColumns: 12 @for $i from 1

    through $totalColumns .grid-#{$i} padding-left: $gutterWidth padding-right: $gutterWidth width: percentage($i / $totalColumns)
  23. /* .css */ .grid-1 { padding-left: 5px; padding-right: 5px; width:

    8.33333%; } .grid-2 { padding-left: 5px; padding-right: 5px; width: 16.66667%; } .grid-3 { padding-left: 5px; padding-right: 5px; width: 25%; } .grid-4 { padding-left: 5px; padding-right: 5px; width: 33.33333%; } .grid-5 { padding-left: 5px; padding-right: 5px; width: 41.66667%; } [...]
  24. /* .css */ .grid-1 { padding-left: 5px; padding-right: 5px; width:

    8.33333%; } .grid-2 { padding-left: 5px; padding-right: 5px; width: 16.66667%; } .grid-3 { padding-left: 5px; padding-right: 5px; width: 25%; } .grid-4 { padding-left: 5px; padding-right: 5px; width: 33.33333%; } .grid-5 { padding-left: 5px; padding-right: 5px; width: 41.66667%; } [...] // .sass $gutterWidth: 5px $totalColumns: 12 @for $i from 1 through $totalColumns .grid-#{$i} padding-left: $gutterWidth padding-right: $gutterWidth width: percentage($i / $totalColumns)
  25. /* .css */ .element { background: #bfbfbf; border-color: rgba(255, 0,

    0, 0.5); color: #385c31; } // .sass .element background: lighten(#000, 75%) border-color: rgba(red, .5) color: darken(#6DAB62, 25%)
  26. // .sass =respond-to($media) @if $media == portrait @media screen and

    (max-width: 320px) @content @else if $media == landscape @media screen and (min-width: 321px) and (max-width: 480px) @content body background: orange +respond-to(portrait) background: blue +respond-to(landscape) background: red h1 color: green +respond-to(portrait) color: yellow +respond-to(landscape) color: purple
  27. /* .css */ body { background: orange; } @media screen

    and (max-width: 320px) { body { background: blue; } } @media screen and (min-width: 321px) and (max-width: 480px) { body { background: red; } } body h1 { color: green; } @media screen and (max-width: 320px) { body h1 { color: yellow; } } @media screen and (min-width: 321px) and (max-width: 480px) { body h1 { color: purple; } }
  28. // .sass %rounded-corners -webkit-border-radius: 15px -moz-border-radius: 15px border-radius: 15px .entry

    background: red @extend %rounded-corners .button background: blue @extend %rounded-corners
  29. /* .css */ .entry, .button { -webkit-border-radius: 15px; -moz-border-radius: 15px;

    border-radius: 15px; } .entry { background: red; } .button { background: blue; }
  30. // .sass %rounded-corners -webkit-border-radius: 15px -moz-border-radius: 15px border-radius: 15px .entry

    background: red @extend %rounded-corners .button background: blue @extend %rounded-corners /* .css */ .entry, .button { -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } .entry { background: red; } .button { background: blue; }
  31. // _variables.sass $default-text-color: #444 $green: #75AA56 // _base.sass * margin:

    0 padding: 0 body background: $green color: $default-text-color // app.sass @import variables @import base
  32. /* app.css */ * { margin: 0; padding: 0; }

    body { background: #75AA56; color: #444; }
  33. // _variables.sass $default-text-color: #444 $green: #75AA56 // _base.sass * margin:

    0 padding: 0 body background: $green color: $default-text-color // app.sass @import variables @import base /* app.css */ * { margin: 0; padding: 0; } body { background: #75AA56; color: #444; }
  34. // .sass $primary-color: red .entry color: $primary-color padding: 15px 30px

    /* .css */ .entry { color: red; padding: 15px 30px; }
  35. // .scss $primary-color: red; .entry { color: $primary-color; padding: 15px

    30px; } /* .css */ .entry { color: red; padding: 15px 30px; }
  36. // .sass $primary-color: red .entry color: $primary-color padding: 15px 30px

    // .scss $primary-color: red; .entry { color: $primary-color; padding: 15px 30px; }
  37. <!-- .html --> <em>Cosby sweater</em> <strong>authentic 8-bit</strong> <div>Helvetica cardigan</div> -#

    .haml %em Cosby sweater %strong authentic 8-bit %div Helvetica cardigan
  38. <!-- .html --> <h1 class=“vip”>American Apparel</h1> <div class=“button”>direct trade</div> <div

    id=”featured” class=“deal”>Deal</div> -# .haml %h1.vip American Apparel .button direct trade #featured.deal Fixed gear
  39. <!-- .html --> <link href=“foo.css” rel=“stylesheet”> <a class=“external” href=“#”>Farm-to-table</a> <input

    type=“checkbox” selected=“selected”> -# .haml %link{:href => “foo.css”, :rel => “stylesheet”} %a.external{href: “#”} Farm-to-table %input(type=“checkbox” selected)
  40. <!-- .html --> <article> <h1><a href=“#”>Selvage</a></h1> <p>Selvage freegan swag cliche

    vinyl bushwick.</p> </article> -# .haml %article %h1 %a{:href => “#”} Groupon %p Selvage freegan swag cliche vinyl bushwick.
  41. !!! 5 %html{lang: "en-us"} %head %meta{charset: "utf-8"} %title Conspirator %link{rel:"stylesheet",

    href: "/stylesheets/main.css"} %body #wrap %header %h1 %a{:href => “/”} Conspirator %nav %ul %li %a{:href => “/about”} About %li %a{:href => “/work”} Work %li %a{:href => “/contact”} Contact %section#main - @entries.each do |entry|
  42. -# .haml %p= [‘Hello’, ‘HTML5’, ‘Conf’].join “ ” = link_to

    ‘View All Names’, names_path, {:class => ‘view-all’}
  43. -# .haml %p= [‘Hello’, ‘HTML5’, ‘Conf’].join “ ” = link_to

    ‘View All Names’, names_path, {:class => ‘view-all’} <!-- .html --> <p>Hello HTML5 Conf</p> <a class=“view-all” href=“/names”>View All Names</a>
  44. -# .haml - foo = “A foolish consistency is the”

    - foo << “ hobgoblin” - foo << “ of little minds.” %p= foo
  45. -# .haml - foo = “A foolish consistency is the”

    - foo << “ hobgoblin” - foo << “ of little minds.” %p= foo <!-- .html --> <p>A foolish consistency is the hobgoblin of little minds.</p>
  46. -# .haml - @articles.each do |article| %article{:id => “post-#{article.id}”} %h3=

    article.title %p.timestamp = article.published_at =article.body
  47. <!-- .html --> <article id=”post-1”> <h2>Mumblecore locavore</h2> <p class=”timestamp”>2012-10-15</p> <p>Austin

    sriracha flexitarian before they sold out food truck american apparel fixie messenger bag.</p> </article> [...]
  48. -# .haml - @articles.each do |article| %article{:id => “post-#{article.id}”} %h3=

    article.title %p.timestamp = article.published_at =article.body <!-- .html --> <article id=”post-1”> <h2>Mumblecore locavore</h2> <p class=”timestamp”>2012-10-15</p> <p>Austin sriracha flexitarian before they sold out food truck american apparel fixie messenger bag.</p> </article> [...]
  49. # .coffee $ -> $(‘a’).click (event) -> event.preventDefault() $(this).addClass ‘do-work’

    // .js $(function(){ $(‘a’).click(function(event){ return $(this).addClass(‘do-work’); }); });
  50. <!-- html --> <script> var a = 1; </script> #

    app.coffee a = 5 console.log a, window.a
  51. <!-- .html --> <script> var a = 1; </script> //

    app.js (function(){ var a; a = 5; console.log(a, window.a); })();
  52. <!-- .html --> <script> var a = 1; </script> #

    app.coffee a = 5 console.log a, window.a <!-- .html --> <script> var a = 1; </script> // app.js (function(){ var a; a = 5; console.log(a, window.a); })();
  53. # .coffee meal = [‘stuffing’, ‘turkey’, ‘pie’] for food in

    meal when food isnt ‘pie’ console.log "#{food} nom nom nom"
  54. // .js var food, meal, _i, _len; meal = ['stuffing',

    'turkey', 'pie']; for (_i = 0, _len = meal.length; _i < _len; _i++){ food = meal[_i]; if (food !== 'pie') { console.log("" + food + " nom nom nom"); } }
  55. # .coffee if theDrink is 'cheap' or 'free' drinkAnother() else

    if theDrink is 'too expensive' drinkSlowly() else trySomethingDifferent()
  56. // .js if (theDrink === 'cheap' || 'free') { drinkAnother();

    } else if (theDrink === 'too expensive') { drinkSlowly(); } else { trySomethingDifferent(); }
  57. # .coffee drink = (beverage) -> alert "Mmm...this #{beverage} is

    good!" twentyOneOrOlder = (age) -> age >= 21 if twentyOneOrOlder 25 then drink 'beer' else drink 'water'
  58. // .js var drink, twentyOneOrOlder; drink = function(beverage) { return

    alert("Mmm...this " + beverage + " is good!"); }; twentyOneOrOlder = function(age) { if (age >= 21) { return true; } else { return false; } }; if (twentyOneOrOlder(25)) { drink('beer'); } else { drink('water'); }
  59. // .js var human; human = { first: “Barack”, last:

    “Obama”, employer: “The American People”, position: “POTUS” }
  60. # .coffee human = first: “Barack” last: “Obama” employer: “The

    American People” position: “POTUS” // .js var human; human = { first: “Barack”, last: “Obama”, employer: “The American People”, position: “POTUS” }
  61. # .coffee $.ajax context: $(“form”) url: “http://foobar.baz” dataType: “json” done:

    (data) -> $r = $(this).find “.response” $f = $(this).find “.form-wrap” $r.find(“h1”).html data.status $f.slideUp -> $r.slideDown()
  62. // .js $.ajax({ context: $(“form”), url: 'http://foobar.baz', dataType: “json”, done:

    function(data) { var $f, $r; $r = $(this).find(“.response”); $f = $(this).find(“.form - wrap”); $r.find(“h1”).html(data.status); return $f.slideUp(function() { return $r.slideDown(); }); } });
  63. # .coffee class DealsView extends Backbone.View id: 'finder-results' className: 'grid_24'

    initialize: -> $('#finder-results').remove() addOne: (model) -> new DealTileView({model}).render() render: -> $('#finder').after @el _.each @collection.models, (model) => @addOne model @
  64. // .js var __hasProp = {}.hasOwnProperty, __extends = function(child, parent)

    { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; this.DealsView = (function(_super) { __extends(DealsView, _super); function DealsView() { return DealsView.__super__.constructor.apply(this, arguments); } DealsView.prototype.id = 'finder-results'; DealsView.prototype.className = 'grid_24'; DealsView.prototype.initialize = function() { return $('#finder-results').remove(); }; DealsView.prototype.addOne = function(model) { return new DealTileView({ model: model }).render(); }; DealsView.prototype.render = function() { var _this = this; $('#finder').after(this.el); _.each(this.collection.models, function(model) { return _this.addOne(model); }); return this; }; return DealsView; })(Backbone.View);
  65. # Sass $ sass --watch app/sass:public/stylesheets # Haml $ haml

    input.haml output.html # CoffeeScript $ coffee --watch --output javascripts/ coffeescripts/
  66. # Install Node.js & NPM $ open http://nodejs.org # Install

    Grunt $ npm install -g grunt # Install Grunt Sass $ npm install grunt-contrib-sass # Install Grunt Haml $ npm install grunt-haml # Install Grunt CoffeeScript $ npm install grunt-contrib-coffee # Configure Project-specific Grunt.js $ open https://gist.github.com/3883732