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

Sass/Compass/LESS: Tips, Tricks & Best Practices

Beau Smith
March 13, 2012

Sass/Compass/LESS: Tips, Tricks & Best Practices

Lessons learned in the CSS (Sass and LESS) trenches by @beau, @xeeton, @fat, and @pengwynn

Beau Smith

March 13, 2012
Tweet

More Decks by Beau Smith

Other Decks in Design

Transcript

  1. TOPICS VARIABLES NESTING OPERATIONS EXTEND FILE ORGANIZATION CONTROL LOGIC ADVANCED

    FEATURES SASS VS. LESS SCSS VS. SASS SYNTAX 2 Thursday, March 15, 12
  2. TOPICS VARIABLES NESTING OPERATIONS EXTEND FILE ORGANIZATION CONTROL LOGIC ADVANCED

    FEATURES SASS VS. LESS SCSS VS. SASS SYNTAX CSS3 FEATURES 2 Thursday, March 15, 12
  3. TOPICS VARIABLES NESTING OPERATIONS EXTEND FILE ORGANIZATION CONTROL LOGIC ADVANCED

    FEATURES SASS VS. LESS SCSS VS. SASS SYNTAX CSS3 FEATURES 2 Thursday, March 15, 12
  4. // variables @default-color: #000 // variables $default-color: #000 LESS SASS

    // mixins =foo($color: #fff) color: $color .bar +foo($default-color) // mixins .foo (@color: #fff) { color: @color; } .bar { .foo(@default-color); } less Sass 4 Thursday, March 15, 12
  5. // variables @default-color: #000 // variables $default-color: #000 LESS SASS

    // mixins =foo($color: #fff) color: $color .bar +foo($default-color) // nesting h1 color: #000 a font-weight: normal &:hover font-weight: bold // mixins .foo (@color: #fff) { color: @color; } .bar { .foo(@default-color); } // nesting h1 { color: #000; a { font-weight: normal; &:hover { font-weight: bold; } } } less Sass 4 Thursday, March 15, 12
  6. h1 { font-family: “Gill Sans”, sans-serif; font-size: 2em; color: #222;

    } h2 { font-family: “Gill Sans”, sans-serif; font-size: 1.25em; color: #666; } p { font-family: Georgia, serif; font-size: 1em; color: #666; } CSS 6 Thursday, March 15, 12
  7. h1 { font-family: “Gill Sans”, sans-serif; font-size: 2em; color: #222;

    } h2 { font-family: “Gill Sans”, sans-serif; font-size: 1.25em; color: #666; } p { font-family: Georgia, serif; font-size: 1em; color: #666; } CSS SCSS $baseline-size: 1em; $baseline-color: #666; $header-font: "Gill Sans", sans-serif; $body-font: Georgia, serif; h1 { font-family: $header-font; font-size: $baseline-size * 2; color: $baseline-color - #444; } h2 { font-family: $header-font; font-size: $baseline-size * 1.25; color: $baseline-color; } p { font-family: $body-font; font-size: $baseline-size; color: $baseline-color; } 6 Thursday, March 15, 12
  8. $page-width: 960px; $page-padding: 70px; .foo { width: $page-width - $page-padding

    * 2; padding: 0 $page-padding; margin-top: 37px; } NUMBERS • Use name to provide more context • Always equation if a number is calculated • If not a variable, numbers should be considered arbitrary values SCSS 7 Thursday, March 15, 12
  9. $baby-blue: #ebf7fc; $lightest-blue: #dbeef5; $lighter-blue: #b5dff1; $light-blue: #7bcbed; $blue: #39b2e5;

    $dark-blue: #0091ce; $darker-blue: #0073a4; $lightest-gray: #f3f3f3; $lighter-gray: #dedede; $light-gray: #b3b3b3; $gray: #838383; $dark-gray: #525252; $darker-gray: #202020; COLORS • Build a library of common brand colors • Add to 147 default named CSS colors SCSS 8 Thursday, March 15, 12
  10. $serif-default: Cambria, "Hoefler Text", Utopia, "Liberation Serif", "Nimbus Roman No9

    L Regular", Times, "Times New Roman", serif; $serif-alt: Constantia, "Lucida Bright", Lucidabright, "Lucida Serif", Lucida, "DejaVu Serif", "Bitstream Vera Serif", "Liberation Serif", Georgia, serif; $sans-serif-default: Frutiger, "Frutiger Linotype", Univers, Calibri, "Gill Sans", "Gill Sans MT", "Myriad Pro", Myriad, "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans-serif; FONTS • Build a library of common font stacks • Just a list of strings (separated by space or comma) http://www.sitepoint.com/eight-definitive-font-stacks/ SCSS 9 Thursday, March 15, 12
  11. $button-primary-label-color: white; $button-primary-base-color: lighten($blue, 20%); $button-primary-highlight-color: lighten($blue, 15%); $button-primary-border-color: lighten($blue,

    10%); $button-primary-shadow-color: $light-gray; $button-secondary-label-color: black; $button-secondary-base-color: darken($gray, 10%); $button-secondary-highlight-color: darken($gray, 15%); $button-secondary-border-color: darken($gray, 20%); $button-secondary-shadow-color: $light-gray; .button-primary { padding: 6px 10px; font-family: "Lucida Grande", sans-serif; font-size: 12px; color: $button-primary-label-color; text-shadow: $button-primary-border-color 0 -1px 0; background-image: -webkit-linear-gradient( bottom, $button-primary-base-color 60%, $button-primary-highlight-color ); border: 1px solid $button-primary-border-color; border-radius: 4px; box-shadow: 0 2px 3px $button-primary-shadow-color; } SKINNING • Variables can declared with other variables • Use more semantic names for easy skinning • Update base, changes cascade SCSS 10 Thursday, March 15, 12
  12. you can use both! == some prefer underscores $my_var Most

    people use dashes $my-var 11 Thursday, March 15, 12
  13. .article { width: 100%; } .article h1 { font-size: 26px;

    } .article .author { font-style: italic; } .article width: 100% h1 font-size: 26px .author font-style: italic CSS SASS 13 Thursday, March 15, 12
  14. .article { width: 100%; } .article h1 { font-size: 26px;

    } .article .author { font-style: italic; } .article width: 100% h1 font-size: 26px .author font-style: italic CSS SASS 13 Thursday, March 15, 12
  15. .article { width: 100%; } .article h1 { font-size: 26px;

    } .article .author { font-style: italic; } .article width: 100% h1 font-size: 26px .author font-style: italic CSS SASS 13 Thursday, March 15, 12
  16. .article { width: 100%; } .article h1 { font-size: 26px;

    } .article .author { font-style: italic; } .article width: 100% h1 font-size: 26px .author font-style: italic CSS SASS 13 Thursday, March 15, 12
  17. .article { width: 100%; } .article h1 { font-size: 26px;

    } .article .author { font-style: italic; } .article width: 100% h1 font-size: 26px .author font-style: italic CSS SASS @media screen and (min-width: 480px) width: 480px h1 font-size: 40px @media screen and (min-width: 480px) { .article { width: 480px; } .article h1 { font-size: 40px; } } 13 Thursday, March 15, 12
  18. .subset-section background-color: #fff width: 960px .subset-skus width: 790px .subset-selection float:

    left width: 790px .registrant-needs margin-bottom: 10px text-align: right .subset-attributes width: 430px float: left .subset-pricing display: block text-align: right .price-special font-size: 11px .currency font-size: 16px CSS SASS 15 Thursday, March 15, 12
  19. .subset-section { background-color: white; width: 960px; } .subset-section .subset-skus {

    width: 790px; } .subset-section .subset-skus .subset-selection { float: left; width: 790px; } .subset-section .subset-skus .subset-selection .registrant-needs { margin-bottom: 10px; text-align: right; } .subset-section .subset-skus .subset-selection .registrant-needs .subset- attributes { width: 430px; float: left; } .subset-section .subset-skus .subset-selection .registrant-needs .subset- attributes .subset-pricing { display: block; text-align: right; } .subset-section .subset-skus .subset-selection .registrant-needs .subset- attributes .subset-pricing .price-special { font-size: 11px; } .subset-section .subset-skus .subset-selection .registrant-needs .subset- attributes .subset-pricing .price-special .currency { font-size: 16px; } .subset-section background-color: #fff width: 960px .subset-skus width: 790px .subset-selection float: left width: 790px .registrant-needs margin-bottom: 10px text-align: right .subset-attributes width: 430px float: left .subset-pricing display: block text-align: right .price-special font-size: 11px .currency font-size: 16px CSS SASS 15 Thursday, March 15, 12
  20. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  21. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  22. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  23. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  24. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  25. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  26. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  27. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  28. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  29. div { color: black; } div .foo { color: black;

    } div .foo { color: black; } div + .foo { color: black; } div.bar { color: black; } div:hover { color: black; } .no-borderradius div { color: black; } .parent div .child { color: black; } div color: black .foo color: black & .foo color: black + .foo color: black &.bar color: black &:hover color: black .no-borderradius & color: black .parent & .child color: black CSS SASS 16 Thursday, March 15, 12
  30. NESTING • group styles together • avoid selector duplication •

    parent selector • keep your code DRY Sass Nesting != HTML Nesting danger 17 Thursday, March 15, 12
  31. @mixin my-button($color, $margin: 5px) { background-color: $color; font-size: 1.2em; margin:

    $margin * 2; } .button { @include my-button(blue); color: white; } .button { background-color: blue; font-size: 1.2em; margin: 10px; color: white; } MIXINS • Reusable elements • Parameterizable (use reasonable defaults) • SASS & LESS have different approaches SCSS CSS 19 Thursday, March 15, 12
  32. =transition-setup($value) opacity: $value .ie8 & @if $value >= 0.5 display:

    block @else display: none TRANSITION SETUP • Opacity transition for modern browsers • Hide/show for IE8 Sass 20 Thursday, March 15, 12
  33. =transition-setup($value) opacity: $value .ie8 & @if $value >= 0.5 display:

    block @else display: none TRANSITION SETUP • Opacity transition for modern browsers • Hide/show for IE8 Sass .hidden-element +transition-setup(0) .visible-element +transition-setup(.5) 20 Thursday, March 15, 12
  34. =transition-setup($value) opacity: $value .ie8 & @if $value >= 0.5 display:

    block @else display: none TRANSITION SETUP • Opacity transition for modern browsers • Hide/show for IE8 Sass .hidden-element { opacity: 0; } .ie8 .foo { display: none; } .visible-element { opacity: 0.5; } .ie8 .bar { display: block; } CSS .hidden-element +transition-setup(0) .visible-element +transition-setup(.5) 20 Thursday, March 15, 12
  35. $geoforms-small-text: 1em !default $geoforms-medium-text: 1.2em !default =geoforms ul line-height: 1

    padding-left: 0 margin: 0 font-size: $geoforms-medium-text color: $gray-dark li display: block padding: 6px 0 4px 120px border-top: 1px solid #eee overflow: hidden &:first-child border-top: none label line-height: 20px +text-shadow($white 0 1px 0) &:first-child float: left width: 100px margin-left: -120px font-weight: bold padding-left: 10px // 75 more lines of form awesomeness… SHARING • Extract common elements • Reuse them in your project or between projects • Distribute it! Sass 21 Thursday, March 15, 12
  36. =my-btn($color) color: $color +my-btn(red) @mixin my-btn($color) { color: $color; }

    @include my-btn(red); SCSS Sass 22 Thursday, March 15, 12
  37. h1 { font-family: “Gill Sans”, sans-serif; font-size: 2em; color: #222;

    } h2 { @extend h1; font-size: 1.25em; } h1, h2 { font-family: “Gill Sans”, sans-serif; font-size: 2em; color: #222; } h2 { font-size: 1.25em; } EXTEND • Allows reuse of CSS using selector inheritance • Sort of like a mixin in practice SCSS CSS 24 Thursday, March 15, 12
  38. .my-layout { margin: 1px; h1 { font-weight: bold; font-size: 2em;

    } h2 { @extend h1; font-size: 1.5em; } } .home-page { @extend .my-layout; } .about-page { @extend .my-layout; } .login-page { @extend .my-layout; } .register-page { @extend .my-layout; } SCSS Note: a fix was pushed shortly after this presentation to reduce the number of selectors created by @extend: https://github.com/nex3/sass/commit/8f4869e608e70d7f468bb463ebfe7a939d834e27 25 Thursday, March 15, 12
  39. .my-layout { margin: 1px; h1 { font-weight: bold; font-size: 2em;

    } h2 { @extend h1; font-size: 1.5em; } } .home-page { @extend .my-layout; } .about-page { @extend .my-layout; } .login-page { @extend .my-layout; } .register-page { @extend .my-layout; } SCSS .my-layout, .home-page, .about-page, .login-page, .register-page { margin: 1px; } .my-layout h1, .home-page h1, .about-page h1, .login-page h1, .register-page h1, .my-layout h2, .home-page .my-layout h2, .my-layout .home-page h2, .about-page .my-layout h2, .my- layout .about-page h2, .login-page .my-layout h2, .my- layout .login-page h2, .register-page .my-layout h2, .my- layout .register-page h2, .my-layout .home-page h2, .home- page .my-layout h2, .home-page h2, .about-page .home-page h2, .home-page .about-page h2, .login-page .home-page h2, .home- page .login-page h2, .register-page .home-page h2, .home- page .register-page h2, .my-layout .about-page h2, .about- page .my-layout h2, .home-page .about-page h2, .about-page .home- page h2, .about-page h2, .login-page .about-page h2, .about- page .login-page h2, .register-page .about-page h2, .about- page .register-page h2, .my-layout .login-page h2, .login- page .my-layout h2, .home-page .login-page h2, .login-page .home- page h2, .about-page .login-page h2, .login-page .about-page h2, .login-page h2, .register-page .login-page h2, .login- page .register-page h2, .my-layout .register-page h2, .register- page .my-layout h2, .home-page .register-page h2, .register- page .home-page h2, .about-page .register-page h2, .register- page .about-page h2, .login-page .register-page h2, .register- page .login-page h2, .register-page h2 { font-weight: bold; font-size: 2em; } .my-layout h2, .home-page h2, .about-page h2, .login-page h2, .register-page h2 { font-size: 1.5em; } CSS Note: a fix was pushed shortly after this presentation to reduce the number of selectors created by @extend: https://github.com/nex3/sass/commit/8f4869e608e70d7f468bb463ebfe7a939d834e27 25 Thursday, March 15, 12
  40. .my-layout { margin: 1px; h1 { font-weight: bold; font-size: 2em;

    } h2 { @extend h1; font-size: 1.5em; } } .home-page { @extend .my-layout; } .about-page { @extend .my-layout; } .login-page { @extend .my-layout; } .register-page { @extend .my-layout; } SCSS .my-layout, .home-page, .about-page, .login-page, .register-page { margin: 1px; } .my-layout h1, .home-page h1, .about-page h1, .login-page h1, .register-page h1, .my-layout h2, .home-page .my-layout h2, .my-layout .home-page h2, .about-page .my-layout h2, .my- layout .about-page h2, .login-page .my-layout h2, .my- layout .login-page h2, .register-page .my-layout h2, .my- layout .register-page h2, .my-layout .home-page h2, .home- page .my-layout h2, .home-page h2, .about-page .home-page h2, .home-page .about-page h2, .login-page .home-page h2, .home- page .login-page h2, .register-page .home-page h2, .home- page .register-page h2, .my-layout .about-page h2, .about- page .my-layout h2, .home-page .about-page h2, .about-page .home- page h2, .about-page h2, .login-page .about-page h2, .about- page .login-page h2, .register-page .about-page h2, .about- page .register-page h2, .my-layout .login-page h2, .login- page .my-layout h2, .home-page .login-page h2, .login-page .home- page h2, .about-page .login-page h2, .login-page .about-page h2, .login-page h2, .register-page .login-page h2, .login- page .register-page h2, .my-layout .register-page h2, .register- page .my-layout h2, .home-page .register-page h2, .register- page .home-page h2, .about-page .register-page h2, .register- page .about-page h2, .login-page .register-page h2, .register- page .login-page h2, .register-page h2 { font-weight: bold; font-size: 2em; } .my-layout h2, .home-page h2, .about-page h2, .login-page h2, .register-page h2 { font-size: 1.5em; } CSS danger Note: a fix was pushed shortly after this presentation to reduce the number of selectors created by @extend: https://github.com/nex3/sass/commit/8f4869e608e70d7f468bb463ebfe7a939d834e27 25 Thursday, March 15, 12
  41. .aaa .bbb .ccc { margin: 1px; } .xxx .yyy .zzz

    { @extend .ccc; } .aaa .bbb .ccc, .aaa .bbb .xxx .yyy .zzz, .xxx .yyy .aaa .bbb .zzz { margin: 1px; } DANGERS • Pay attention to CSS output; because, • Selector length can grow wildly out of control • This is less of an issue than it was SCSS CSS Note: a fix was pushed shortly after this presentation to reduce the number of selectors created by @extend: https://github.com/nex3/sass/commit/8f4869e608e70d7f468bb463ebfe7a939d834e27 26 Thursday, March 15, 12
  42. /* Reset CSS */ *{padding:0;margin:0} /* Global Styles */ h1{}

    p{} /* Layout Styles */ .wrapper{} .sidebar{} /* Page-Specific Styles */ .home-page h1{} .about-page h1{} .contact-page h1{} screen.css CSS 28 Thursday, March 15, 12
  43. /* Reset CSS */ *{padding:0;margin:0} /* Global Styles */ h1{}

    p{} /* Layout Styles */ .wrapper{} .sidebar{} /* Page-Specific Styles */ .home-page h1{} .about-page h1{} .contact-page h1{} screen.css CSS CSS Comments 28 Thursday, March 15, 12
  44. /* Reset CSS */ @import "reset.css"; /* Global Styles */

    @import "global.css"; /* Layout Styles */ @import "layout.css"; /* Page-Specific Styles */ @import "pages/home.css"; @import "pages/about.css"; @import "pages/contact.css"; screen.css CSS 29 Thursday, March 15, 12
  45. /* Reset CSS */ @import "reset.css"; /* Global Styles */

    @import "global.css"; /* Layout Styles */ @import "layout.css"; /* Page-Specific Styles */ @import "pages/home.css"; @import "pages/about.css"; @import "pages/contact.css"; screen.css CSS danger excessive http requests 29 Thursday, March 15, 12
  46. html <!-- Reset CSS --> <link rel="stylesheet" href="reset.css"> <!-- Global

    Styles --> <link rel="stylesheet" href="global.css"> <!-- Layout Styles --> <link rel="stylesheet" href="layout.css"> <!-- Page-Specific Styles --> <link rel="stylesheet" href="pages/about.css"> about.html 30 Thursday, March 15, 12
  47. html <!-- Reset CSS --> <link rel="stylesheet" href="reset.css"> <!-- Global

    Styles --> <link rel="stylesheet" href="global.css"> <!-- Layout Styles --> <link rel="stylesheet" href="layout.css"> <!-- Page-Specific Styles --> <link rel="stylesheet" href="pages/about.css"> about.html danger excessive http requests 30 Thursday, March 15, 12
  48. /* Reset CSS */ *{padding:0;margin:0} /* Global Styles */ h1{}

    p{} /* Layout Styles */ .wrapper{} .sidebar{} /* Page-Specific Styles */ .home-page h1{} .about-page h1{} .contact-page h1{} screen.css CSS 31 Thursday, March 15, 12
  49. // Reset CSS * padding: 0 margin: 0 // Global

    Styles h1 /* styles here */ p /* styles here */ // Layout Styles .wrapper /* styles here */ .sidebar /* styles here */ // Page-Specific Styles .home-page h1 color: red screen.sass Sass 32 Thursday, March 15, 12
  50. // Reset CSS @import reset // Global Styles h1 /*

    styles here */ p /* styles here */ // Layout Styles .wrapper /* styles here */ .sidebar /* styles here */ // Page-Specific Styles .home-page h1 color: red .about-page h1 color: white screen.sass Sass // Reset CSS * padding: 0 margin: 0 _reset.sass 33 Thursday, March 15, 12
  51. // Reset CSS @import reset // Global Styles @import global

    // Layout Styles .wrapper /* styles here */ .sidebar /* styles here */ // Page-Specific Styles .home-page h1 color: red .about-page h1 color: white .contact-page h1 color: blue screen.sass Sass // Global Styles h1 /* styles here */ p /* styles here */ _global.sass 34 Thursday, March 15, 12
  52. // Reset CSS @import reset // Global Styles @import global

    // Layout Styles @import layout // Page-Specific Styles .home-page h1 color: red .about-page h1 color: white .contact-page h1 color: blue screen.sass Sass // Layout Styles .wrapper /* styles here */ .sidebar /* styles here */ _layout.sass 35 Thursday, March 15, 12
  53. // Reset CSS @import reset // Global Styles @import global

    // Layout Styles @import layout // Page-Specific Styles .home-page @import home .about-page @import about-page .contact-page @import contact-page screen.sass Sass 36 Thursday, March 15, 12
  54. // Page-Specific Styles .home-page @import home screen.sass Sass // home

    page styles h1 color: red p color: blue _home.sass 37 Thursday, March 15, 12
  55. // Page-Specific Styles .home-page @import home screen.sass Sass screen.css .home-page

    h1 { color: red; } .home-page p { color: blue; } // home page styles h1 color: red p color: blue _home.sass CSS 37 Thursday, March 15, 12
  56. // Page-Specific Styles .home-page @import home screen.sass Sass screen.css .home-page

    h1 { color: red; } .home-page p { color: blue; } // home page styles h1 color: red p color: blue _home.sass CSS css/ screen.css sass/ _home.sass screen.sass 37 Thursday, March 15, 12
  57. PARTIALS • Faster Sass compilation • Shareable components • Explicit

    definition of purpose • DRY css/ screen.css sass/ _global.sass _layout.sass _reset.sass screen.sass 38 Thursday, March 15, 12
  58. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  59. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  60. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  61. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  62. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  63. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  64. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  65. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  66. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  67. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  68. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  69. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  70. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  71. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  72. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  73. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  74. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  75. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  76. // Public Styles // All styles included in the following

    partials should have low specificity // such that page-specific stylesheets can extend (or override) these styles // Libraries @import compass @import public/config @import public/reset @import shared/avantgarde @import public/mixins @import public/sprites @import shared/payment_types // Typography @import public/type_styles @import public/type_layout @import public/links @import public/pagination PARTIAL STRATEGY Sass // Layout @import public/layout @import public/lightbox @import public/images // Forms @import public/form_styles @import public/form_layout @import public/messaging 39 Thursday, March 15, 12
  77. <div class="pseudo-meter value-2">2</div> <div class="pseudo-meter value-1">1</div> <div class="pseudo-meter value-5">5</div> .pseudo-meter

    { display: block; height: 20px; text-indent: -9999px; background-color: gray; @for $i from 0 through 10 { &.value-#{$i} { width: $i * 10%; @if $i > 7 { background-color: red; } } } } .pseudo-meter.value-0 { width: 0%; } .pseudo-meter.value-1 { width: 20%; } .pseudo-meter.value-2 { width: 40%; } .pseudo-meter.value-3 { width: 60%; } .pseudo-meter.value-4 { width: 80%; } .pseudo-meter.value-5 { width: 100%; } • Simple “meter-like” element • Change color above certain threshold SCSS CSS html 41 Thursday, March 15, 12
  78. @mixin pseudo-meter($height, $limit: 7) { display: block; height: $height; text-indent:

    -9999px; background-color: gray; @for $i from 0 through 10 { &.value-#{$i} { width: $i * 10%; @if $i > $limit { background-color: red; } } } } .pseudo-meter (@height, @limit: 7) { display: block; height: @height; text-indent: -9999px; background-color: gray; .bg (@i) when (@i > @limit) { background-color: red; } .bg (@i) {} .loop (@i) when (@i > 0) { (~”.value-@{i}”) { width: @i * 10%; .bg(@i); } .loop(@i - 1); } .loop (0) {} .loop(10); } LESS SCSS 42 Thursday, March 15, 12
  79. .mixin (@a) when (lightness(@a) > 50%) { background-color: black; }

    .mixin (@a) when (lightness(@a) < 50%) { background-color: white; } GUARDS • expression matching • declarative • looks like @media LESS 44 Thursday, March 15, 12
  80. .mixin (@a) when (isnumber(@a)) { /* some stuff */ }

    .mixin (@a) when (iscolor(@a)) { /* some stuff */ } .mixin (@a) when (isurl(@a)) { /* some stuff */ } .mixin (@a) when (ispercentage(@a)) { /* some stuff */ } TYPE CHECKING • unit types • px, %, em • entitity types • color, #, str, etc… LESS 45 Thursday, March 15, 12
  81. .mixin (12) { background-color: black; } .mixin (@fat) { background-color:

    black; } .mixin (...) { background-color: black; } PATTERN MATCHING • conditional execution • based on arguments • varargs (v1.3+) NEW! LESS 46 Thursday, March 15, 12
  82. li.error { background-color: #fdd; border-top-color: #fff; @include background-image(linear-gradient( left, #fff9f9,

    #ffeeee 20%, #ffeeee 80%, #fff9f9 )); } li.error { background-color: #ffdddd; border-top-color: white; background-image: -webkit-gradient( linear, 0% 50%, 100% 50%, color-stop(0%, #fff9f9), color-stop(20%, #ffeeee), color-stop(80%, #ffeeee), color-stop(100%, #fff9f9) ); background-image: -moz-linear-gradient( left, #fff9f9, #ffeeee 20%, #ffeeee 80%, #fff9f9 ); background-image: linear-gradient( left, #fff9f9, #ffeeee 20%, #ffeeee 80%, #fff9f9 ); } CSS3 • Use CSS3 now! • Single, common syntax • Let the Compass team worry about browser support SCSS CSS 49 Thursday, March 15, 12
  83. @import "compass/css3" @import "compass/css3/border-radius"; @import "compass/css3/inline-block"; @import "compass/css3/opacity"; @import "compass/css3/box-shadow";

    @import "compass/css3/text-shadow"; @import "compass/css3/columns"; @import "compass/css3/box-sizing"; @import "compass/css3/box"; @import "compass/css3/gradient"; @import "compass/css3/images"; @import "compass/css3/background-clip"; @import "compass/css3/background-origin"; @import "compass/css3/background-size"; @import "compass/css3/font-face"; @import "compass/css3/transform"; @import "compass/css3/transition"; @import "compass/css3/appearance"; JUST DO THIS SCSS 50 Thursday, March 15, 12
  84. nav { background: image-url("nav_bg.png"); } .logo { background: inline-image("logo.png"); }

    nav { background: url(/images/nav_bg.png); } .logo { background: url( data:image/png;base64,iVBORw0KGgo...); } nav { background: url( http://cdn.example.com/images/nav_bg.png); } .logo { background: url( data:image/png;base64,iVBORw0KGgo...); } URL HELPERS • Relative paths for assets in development, absolute for production CDNs • Inline images and fonts Dev PRO SCSS CSS 51 Thursday, March 15, 12
  85. #{headings()} { line-height: 1.25em; } #{headings(2,6)} { font-weight: normal; }

    #{elements-of-type(block)} { margin: 10px 0; } h1,h2,h3,h4,h5,h6 { line-height: 1.25em; } h2,h3,h4,h5,h6 { font-weight: normal; } address, article, aside, blockquote, center, dd, details, dir, div, dl, dt, fieldset, figcaption, figure, footer, form, frameset, h1, h2, h3, h4, h5, h6, header, hgroup, hr, isindex, menu, nav, noframes, noscript, ol, p, pre, section, summary, ul { margin: 10px 0; } UTILITY HELPERS • Headings: all or range • Elements of type: inline, block, html5-inline, html5-block, more SCSS CSS 52 Thursday, March 15, 12
  86. rgba($color, $alpha) Adds an alpha layer to any color value.

    mix($color-1, $color-2, [$weight]) Mixes two colors together. hsla($color, $alpha) Adds an alpha layer to any color value. lighten($color, $amount) Makes a color lighter. darken($color, $amount) Makes a color darker. saturate($color, $amount) Makes a color more saturated. desaturate($color, $amount) Makes a color less saturated. grayscale($color) Converts a color to grayscale. complement($color) Returns the complement of a color. invert($color) Returns the inverse of a color. COLOR FUNCTIONS • Add alpha to hex • Work in HSL, support IE • Find safe colors automagically 53 Thursday, March 15, 12
  87. @import "compass/typography/vertical_rhythm"; $base-font-size: 16px; $base-line-height: 24px; @include establish-baseline; body {

    font-family: 'Helvetica Neue', sans-serif; @include debug-vertical-alignment( "../images/debug.png"); } h1 {@include adjust-font-size-to(48px)} h2 {@include adjust-font-size-to(36px)} h3 {@include adjust-font-size-to(24px)} h4 {@include adjust-font-size-to(20px)} h5 {@include adjust-font-size-to(18px)} p {@include leader; @include trailer;} h2.important {@include leader(2); @include trailer(2)} TYPOGRAPHY • Vertical rhythm • Add padding, margin in rhythm units SCSS 54 Thursday, March 15, 12
  88. @mixin border-radius ($radii) { -webkit-border-radius: $radii; -moz-border-radius: $radii; border-radius: $radii;

    } @function golden-ratio(($value, $increment) { @return modular-scale($value, $increment, 1.618) } div { font-size: modular-scale(14px, 1, 1.618); } div { font-size: 22.652px; } MORE VANILLA CSS3 • No syntax abstraction • Use shorthands • A few added functions • Simply patterns, no packaging SCSS CSS 56 Thursday, March 15, 12
  89. SPRITES • Fewer images = fewer http requests • How

    many? • HTML element? 58 Thursday, March 15, 12
  90. SPRITES • Fewer images = fewer http requests • How

    many? • HTML element? <div> or <i> HTML 58 Thursday, March 15, 12
  91. SPRITES • Fewer images = fewer http requests • How

    many? • HTML element? <div> or <i> // <i> is a sprite container i display: block HTML Sass 58 Thursday, March 15, 12
  92. $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites <i class="card-visa"></i> HTML SASS SPRITES

    american-express.png discover.png mastercard.png visa.png card 59 Thursday, March 15, 12
  93. $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites <i class="card-visa"></i> HTML card-s1234567890.png SASS

    SPRITES american-express.png discover.png mastercard.png visa.png card 59 Thursday, March 15, 12
  94. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background:

    url('../images/card-s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; height: 22px; width: 32px; } .card-discover { background-position: 0 -66px; height: 22px; width: 32px; } .card-mastercard { background-position: 0 0; height: 22px; width: 32px; } .card-visa { background-position: 0 -44px; height: 22px; width: 32px; } <i class="card-visa"></i> HTML SASS $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites 60 Thursday, March 15, 12
  95. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background:

    url('../images/card-s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; height: 22px; width: 32px; } .card-discover { background-position: 0 -66px; height: 22px; width: 32px; } .card-mastercard { background-position: 0 0; height: 22px; width: 32px; } .card-visa { background-position: 0 -44px; height: 22px; width: 32px; } danger Duplicated dimensions <i class="card-visa"></i> HTML SASS $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites 60 Thursday, March 15, 12
  96. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background:

    url('../images/card-s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; height: 22px; width: 32px; } .card-discover { background-position: 0 -66px; height: 22px; width: 32px; } .card-mastercard { background-position: 0 0; height: 22px; width: 32px; } .card-visa { background-position: 0 -44px; height: 22px; width: 32px; } danger Duplicated dimensions <i class="card-visa"></i> HTML SASS $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites 60 Thursday, March 15, 12
  97. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background:

    url('../images/card-s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; height: 22px; width: 32px; } .card-discover { background-position: 0 -66px; height: 22px; width: 32px; } .card-mastercard { background-position: 0 0; height: 22px; width: 32px; } .card-visa { background-position: 0 -44px; height: 22px; width: 32px; } <i class="card-visa"></i> HTML SASS $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites 60 Thursday, March 15, 12
  98. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background:

    url('../images/card-s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; height: 22px; width: 32px; } .card-discover { background-position: 0 -66px; height: 22px; width: 32px; } .card-mastercard { background-position: 0 0; height: 22px; width: 32px; } .card-visa { background-position: 0 -44px; height: 22px; width: 32px; } <i class="card-visa"></i> HTML SASS $card-sprite-dimensions: true @import "card/*.png" +all-card-sprites 61 Thursday, March 15, 12
  99. CSS SPRITES <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width:

    image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 62 Thursday, March 15, 12
  100. CSS SPRITES <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width:

    image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 62 Thursday, March 15, 12
  101. CSS SPRITES <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width:

    image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 62 Thursday, March 15, 12
  102. CSS SPRITES <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width:

    image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 63 Thursday, March 15, 12
  103. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { width:

    32px; height: 22px; } .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background: url('../images/card- s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; } .card-discover { background-position: 0 -66px; } .card-mastercard { background-position: 0 0; } .card-visa { background-position: 0 -44px; } <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width: image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 63 Thursday, March 15, 12
  104. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { width:

    32px; height: 22px; } .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background: url('../images/card- s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; } .card-discover { background-position: 0 -66px; } .card-mastercard { background-position: 0 0; } .card-visa { background-position: 0 -44px; } <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width: image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 63 Thursday, March 15, 12
  105. CSS SPRITES .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { width:

    32px; height: 22px; } .card-sprite, .card-american-express, .card- discover, .card-mastercard, .card-visa { background: url('../images/card- s3c04635c42.png') no-repeat; } .card-american-express { background-position: 0 -22px; } .card-discover { background-position: 0 -66px; } .card-mastercard { background-position: 0 0; } .card-visa { background-position: 0 -44px; } <i class="card-visa"></i> HTML SASS $card-visa-image: "card/visa.png" .card-sprite width: image-width($card-visa-image) height: image-height($card-visa-image) @import "card/*.png" +all-card-sprites 63 Thursday, March 15, 12