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

Keeping your Sass squeaky clean - SassConf 2014

Fc7368fd45560e1e7401bc80684f5867?s=47 Adam Onishi
October 02, 2014

Keeping your Sass squeaky clean - SassConf 2014

In this talk, I will take a look at all the features Sass and Compass put at your disposal, showing you how they can be used in real-world situations with a case study from the new Persil.co.uk website. From making complex responsive front end builds more manageable, working with custom IE style sheets, all the way through to improving the consistency amongst a team of developers. All of this formed part of the work that went into the new Persil website. In the last few years we’ve become quite accustomed to increasing our productivity with preprocessors like Sass or LESS. But how many of us take it much further than using a few variables, nesting our selectors, and using partials. Sass brings much more functionality to the table, including loops, conditionals, functions, and mixins. Now bring Compass into the mix and you have an even more powerful combination with added functions and built-in mixins. I'll show you how you can start cleaning up your own Sass with these advanced techniques that we've been using in the Persil project.

Fc7368fd45560e1e7401bc80684f5867?s=128

Adam Onishi

October 02, 2014
Tweet

Transcript

  1. @onishiweb Keeping Your Sass Squeaky Clean Adam Onishi SassConf 2014

    - New York
  2. @onishiweb Good morning!

  3. @onishiweb Hello https://www.flickr.com/photos/simon__syon/8187169079/

  4. @onishiweb Hello

  5. @onishiweb Squeaky clean Sass?

  6. @onishiweb – Drew McLellan @drewm “Sass is like an F1

    car. It’s powerful and fast, but you need a lot of skill not to die in a fiery ball.” Squeaky
  7. @onishiweb maintainable? Understandable? Extendable? Squeaky

  8. @onishiweb The Project

  9. @onishiweb Project

  10. @onishiweb Team

  11. @onishiweb • External design company • team of developers •

    35 markets worldwide • … Project
  12. @onishiweb Warning! Contains WordPress

  13. @onishiweb • Multisite • Parent & Child themes • Single

    codebase Project
  14. @onishiweb Sass & Compass Project

  15. @onishiweb Getting Sassy

  16. @onishiweb • Architecture • Sass helpers/mixins • Compass • Working

    with a Team Sassy
  17. @onishiweb #codelicious @sturobson Sassy http://sass.rocks/news

  18. @onishiweb – Stu Robson @sturobson “Helps you care about your

    work. Makes you aware of what you're doing. Gives understanding as to what you're doing. Helps others comprehend what you've done.” http://bit.ly/stus-codelicious Sassy
  19. @onishiweb Architecture

  20. @onishiweb File Organisation Architecture

  21. @onishiweb themes/ |- core/ |- brazil/ |- chile/ |- china/

    |- indonesia/ |- portugal/ |- uk/ Architecture
  22. @onishiweb scss/ |- core/ |- brazil/ |- chile/ |- china/

    |- indonesia/ |- portugal/ |- uk/ Architecture
  23. @onishiweb # Require any additional compass plugins here. ! #

    Set this to the root of your project when deployed: http_path = "/" css_dir = "public/wp-content/themes" sass_dir = "app/scss" javascripts_dir = "app/js" ! fonts_dir = "public/wp-content/assets/fonts" fonts_path = "public/wp-content/assets/fonts" ! http_fonts_path = "/wp-content/assets/fonts" http_fonts_dir = "../../assets/fonts" ! images_dir = "public/wp-content/assets/images" ! http_generated_images_path = "/wp-content/assets/images" http_images_path = "../../assets/images" Hello! Architecture
  24. @onishiweb # Set this to the root of your project

    when # deployed: http_path = "/" css_dir = "public/wp-content/themes" sass_dir = "app/scss" Hello! Architecture
  25. @onishiweb scss/ |- uk/ | |- style.scss | |- ie.scss

    |- indonesia/ | |- style.scss | |- ie.scss Architecture
  26. @onishiweb themes/ |- uk/ | |- style.css | |- ie.css

    |- indonesia/ | |- style.css | |- ie.css Architecture
  27. @onishiweb Components Architecture

  28. @onishiweb core/ |- templates/ | |- offers-and-promotions.php | |- parallax.php

    |- partials/ | |- navigation.php | |- content-cross-link.php |- 404.php |- front-page.php |- page-contact-us.php Architecture
  29. @onishiweb core/ |- partials/ | |- pages/ | | |-

    _404.scss | | |- _front-page.scss | | |- _contact-us.scss | | |- _offers-and-promotions.scss | |- components/ | | |- _navigation.scss | | |- _cross-link.scss Architecture
  30. @onishiweb Tightly coupling templates & Sass Architecture

  31. @onishiweb Variables Architecture

  32. @onishiweb $font-body $font-headers ! $clr-brand $clr-kids-activities $clr-parenting ! $img-dash-brand $img-dash-kids-activities

    Architecture
  33. @onishiweb $clr-brand:#4BCEFA !default; $clr-kids-activities:#F96EC4 !default; $clr-parenting:#FFB400 !default; $clr-sustainability:#8DD400 !default; $clr-mmr:#009edc

    !default; Architecture
  34. @onishiweb Architecture

  35. @onishiweb Architecture

  36. @onishiweb Layout & Grid Architecture

  37. @onishiweb .grid--half { @extend %grid__item; ! @extend %small--one-half; } !

    .grid--whole-whole-half { @extend %grid__item; ! @extend %small--one-whole; @extend %large--one-half; } Architecture
  38. @onishiweb .grid--whole-half-third { @extend %grid__item; ! @extend %small--one-whole; @extend %medium--one-half;

    @extend %large--one-third; ! @include breakpoint(large) { &:nth-of-type(3n + 1) { clear:left; } } } Architecture
  39. @onishiweb Sass Helpers/Mixins

  40. @onishiweb Media Queries Helpers/mixins

  41. @onishiweb $breakpoints: ( 'small' 25em, 'medium' 35em, 'large' 62.5em );

    Helpers/mixins https://github.com/csswizardry/csswizardry-grids
  42. @onishiweb $fix-mqs:false !default; ! @mixin respond-min($width) { // If we're

    outputting for a fixed media query set... @if $fix-mqs { // ...and if we should apply these rules... @if $fix-mqs >= $width { // ...output the content the user gave us. @content; } } @else { // Otherwise, output it using a regular media query @media screen and (min-width: $width) { @content; } } } Helpers/mixins http://jakearchibald.github.io/sass-ie/
  43. @onishiweb @mixin breakpoint($point) { // Get the width of the

    query based on the passed $point variable $width: get-list-value($breakpoints, $point); ! @if $fix-mqs { @if $fix-mqs >= $width { @content; } } @else { @media screen and (min-width: $width) { @content; } } } Helpers/mixins https://github.com/bpscott/breakup
  44. @onishiweb .site-nav-bar { width:100%; height:50px; ! @include breakpoint(large) { width:300px;

    height:100%; } } Helpers/mixins
  45. @onishiweb .a-selector { … ! @include breakpoint(large) { … }

    @include tweakpoint(40em) { … } @include max-breakpoint(small) { … } } Helpers/mixins
  46. @onishiweb @mixin old-ie { // Only use this content if

    we're dealing with old IE @if $old-ie { @content; } } ! // Example .outer-container { width:100%; margin:0; ! @include old-ie { width:1000px; } } Helpers/mixins http://jakearchibald.github.io/sass-ie/
  47. @onishiweb // ie.scss ! // Set up defaults and max

    size of page, then // import core ! $old-ie:true; $fix-mqs:63em; // 1000px @import 'core'; Helpers/mixins
  48. @onishiweb REMs Helpers/mixins

  49. @onishiweb // Rems with pixel fallback for any property @mixin

    rem($property, $px-values, $baseline-px: $base-font-size) { // Convert the baseline into rems $baseline-rem: $baseline-px / 1rem; ! // Create an empty list that we can dump values into $rem-values: (); @each $value in $px-values { // If the value is zero, return 0 $rem-values: append($rem-values, if($value == 0, $value, $value / $baseline-rem)); } ! // Output the property's px and rem values #{$property}: $px-values; #{$property}: $rem-values; } Helpers/mixins https://github.com/BPScott/bpscott.github.io/blob/develop/source/stylesheets/vendor/_rem.scss
  50. @onishiweb @mixin font-size($size) { @include rem('font-size', $size + px); }

    ! // Example usage .selector { @include font-size(20); } Helpers/mixins
  51. @onishiweb Extending carefully Helpers/mixins

  52. @onishiweb %clearfix { zoom:1; &:before, &:after { content: '\0020'; display:

    block; height: 0; overflow: hidden; } &:after { clear: both; } } Helpers/mixins
  53. @onishiweb /* Hide the text of an element - for

    use with buttons with background images etc */ %hide-text { display:block; text-indent:100%; white-space:nowrap; overflow:hidden; } ! /* Hide from both screenreaders and browsers: h5bp.com/u */ %hidden { display:none !important; visibility:hidden; } Helpers/mixins
  54. @onishiweb .button-square, %button-square { display:inline-block; margin:0 0 $baseline; padding:5px 7px;

    color:#fff; @include rem('font-size', 14px); line-height:1; font-weight:normal; text-transform:uppercase; background-color:$clr-brand; } Helpers/mixins http://csswizardry.com/2014/01/extending-silent-classes-in-sass/
  55. @onishiweb Compass

  56. @onishiweb Images Compass

  57. @onishiweb wp-content/ |- assets/ | |- fonts/ | |- images/

    | | |- uk/ | | |- brazil/ | | |- portugal/ Compass
  58. @onishiweb wp-content/ |- assets/ | |- fonts/ | |- images/

    | | |- common/ | | |- page-headers/ | | |- lightbox/ Compass
  59. @onishiweb # Require any additional compass plugins here. ! #

    Set this to the root of your project when deployed: http_path = "/" css_dir = "public/wp-content/themes" sass_dir = "app/scss" javascripts_dir = "app/js" ! fonts_dir = "public/wp-content/assets/fonts" fonts_path = "public/wp-content/assets/fonts" ! http_fonts_path = "/wp-content/assets/fonts" http_fonts_dir = "../../assets/fonts" ! images_dir = "public/wp-content/assets/images" ! http_generated_images_path = "/wp-content/assets/images" http_images_path = "../../assets/images" Hello! Compass
  60. @onishiweb # General images directory images_dir = "public/wp-content/assets/images" ! #

    Image paths full and relative paths http_generated_images_path = "/wp-content/assets/images" http_images_path = "/wp-content/assets/images" Hello! Compass
  61. @onishiweb image-url(‘common/site-bg.jpg') // Outputs: // url(/wp-content/assets/images/common/site-bg.jpg) ! // Image dimensions

    image-width('smartgold/play.png'); image-height(‘smartgold/play.png'); Hello! Compass
  62. @onishiweb @mixin bg-image($img, $img-2x:false) { width:image-width($img); height:image-height($img); background:image-url($img) no-repeat 0

    0; ! @if $img-2x { @include hidpi-query() { width:image-width($img-2x)/2; height:image-height($img-2x)/2; background:image-url($img-2x) no-repeat 0 0; background-size:(image-width($img-2x)/2) (image- height($img-2x)/2); } } } Hello! Compass
  63. @onishiweb Inline Images Compass

  64. @onishiweb .logo { background-image:inline-image('12devslogo.png'); } Hello! Compass

  65. @onishiweb Compass

  66. @onishiweb Compass

  67. @onishiweb Sprites Compass

  68. @onishiweb images/site-icons/new.png images/site-icons/edit.png images/site-icons/save.png images/site-icons/delete.png Hello! Compass

  69. @onishiweb @import "compass/utilities/sprites"; @import "site-icons/*.png"; @include all-site-icons-sprites; Hello! Compass

  70. @onishiweb .site-icons-sprite, .site-icons-delete, .site-icons-edit, .site-icons-new, .site-icons-save { background: url('/images/site-icons- s34fe0604ab.png')

    no-repeat; } ! .site-icons-delete { background-position: 0 0; } .site-icons-edit { background-position: 0 -32px; } .site-icons-new { background-position: 0 -64px; } .site-icons-save { background-position: 0 -96px; } Hello! Compass
  71. @onishiweb @import "site-icons/*.png"; ! .actions { .new { @include site-icons-sprite(new);

    } .edit { @include site-icons-sprite(edit); } .save { @include site-icons-sprite(save); } .delete { @include site-icons-sprite(delete); } } Hello! Compass
  72. @onishiweb Sprites Compass

  73. @onishiweb Colours Compass

  74. @onishiweb adjust-lightness($color, $amount); ! adjust-saturation($color, $amount); ! scale-lightness($color, $amount); !

    scale-saturation($color, $amount); ! shade($color, $percentage); ! tint($color, $percentage); Hello! Compass
  75. @onishiweb $clr-brand-hover:shade( $clr-brand, 10% ); ! $clr-kids-activities-hover:shade( $clr-kids-activities, 10% );

    ! $clr-sustainability-hover:shade( $clr-sustainability, 10% ); ! $clr-parenting-hover:shade( $clr-parenting, 10% ); ! $clr-mmr-hover:shade( $clr-mmr, 10% ); Hello! Compass
  76. @onishiweb css3 Mixins Compass

  77. @onishiweb @include border-radius($radius 0 0 $radius); ! @include box-shadow(0 0

    4px rgba(#000, 0.2)); ! @include transform( scale(1.1) ); ! @include transition(color 0.2s ease); ! @include transition(background-color 0.2s ease); Hello! Compass
  78. @onishiweb Build tools Compass

  79. @onishiweb // & runs the command in the background //

    in terminal. Freeing up your command line ! > compass watch & > grunt watch & Hello! Compass
  80. @onishiweb Working with a team

  81. The Architect dev team, my team! Or funny gif! Justice

    League? @onishiweb Team
  82. @onishiweb Common starting point Team

  83. @onishiweb Boilerplates Team

  84. @onishiweb Team

  85. @onishiweb Front-end Boilerplate Team https://github.com/wearearchitect/Frontend-Boilerplate

  86. @onishiweb Team

  87. @onishiweb Share Team

  88. @onishiweb Developer Déjeuner Team

  89. The Architect dev team, my team! Or funny gif! Justice

    League? @onishiweb Team
  90. @onishiweb Tools specialist Team

  91. @onishiweb Lightning fast coder Team

  92. @onishiweb … Team

  93. @onishiweb – Rick Waldron (idiomatic.js) “Every line of code should

    appear to be written by a single person, no matter the number of contributors.” Team
  94. @onishiweb Team

  95. @onishiweb Team

  96. @onishiweb Team

  97. @onishiweb http://cssguidelin.es/ http://codeguide.co/ https://github.com/stubbornella/oocss-code-standards https://github.com/necolas/idiomatic-css https://github.com/anthonyshort/idiomatic-sass https://github.com/cxpartners/coding-standards http://isobar-idev.github.io/code-standards/ http://tmwagency.github.io/TMW-frontend-guidelines/ Team

  98. @onishiweb – Mark Otto @mdo (codeguide.co) “Enforce these, or your

    own, agreed upon guidelines at all times. Small or large, call out what's incorrect.” Team
  99. @onishiweb Team

  100. @onishiweb Team

  101. @onishiweb The Rules https://github.com/wearearchitect/Frontend-Rules Team

  102. @onishiweb Team

  103. @onishiweb Rule 1: Obey the rules ! Where possible all

    of these rules should be followed to the letter. But, all rules are open to discussion and review. Obviously there are also times where a rule must be broken, but you should be able to explain why it was necessary and what benefit it gave you. Team
  104. @onishiweb Rule 4: It's all about the bike code. !

    None of these rules are personal, there is no agenda in the rules; it's all about the code. The rules are here to help us write good code and work together as a team. It's about learning as well, front end development is continually evolving with new techniques and new tools becoming available all the time, the rules will keep evolving with these best practices and be updated over time. Team
  105. @onishiweb Rule 12: The correct number of JavaScript libraries to

    know is n+1 ! Most front end developers are familiar with JavaScript and jQuery, but there are now more frameworks than you can shake a stick at! Whether it's Angular, Meteor, Backbone, Ember, Coffeescript, or Node.js there's always something new to learn. Team
  106. @onishiweb Code Reviews Team

  107. @onishiweb Team

  108. @onishiweb Rule 2: Lead by example ! You should make

    yourself familiar with the rules inside and out and ensure your code always follows the rules. Code reviews will be employed and pull requests will be declined if you're found to be breaking the rules. Team
  109. @onishiweb Team

  110. @onishiweb Rule 3: Guide the uninitiated ! You should help

    others follow the rules. Code reviews and pair programming are encouraged. Do your best to make yourself available for code reviews when possible, or make sure if you're a reviewer on a pull request you review the code thoroughly. If code is breaking the rules, comment and state the rule number the coder should check their code against. Team
  111. @onishiweb is that Squeaky clean?

  112. @onishiweb Architecture Squeaky

  113. @onishiweb Tightly coupled Squeaky

  114. @onishiweb Sass & Compass Squeaky

  115. @onishiweb A Team on the same page Squeaky

  116. @onishiweb Not just technical Squeaky

  117. @onishiweb … Squeaky

  118. @onishiweb Future

  119. @onishiweb Refactoring Future

  120. @onishiweb – Jack Franklin @Jack_Franklin “Refactoring is for people with

    their priorities in order.” Future
  121. @onishiweb My refactoring journey Future

  122. @onishiweb Switching to Maps Future

  123. @onishiweb @mixin breakpoint($point) { // Get the width of the

    query based on the passed $point variable $width: get-list-value($breakpoints, $point); ! @if $fix-mqs { @if $fix-mqs >= $width { @content; } } @else { @media screen and (min-width: $width) { @content; } } } Future
  124. @onishiweb @mixin breakpoint($point) { // Get the width of the

    query based on the passed $point variable $width: map-get($breakpoints, $point); ! @if $fix-mqs { @if $fix-mqs >= $width { @content; } } @else { @media screen and (min-width: $width) { @content; } } } Future
  125. @onishiweb Loops Future

  126. @onishiweb $archive-themes: ( 'default': ( 'color': $clr-brand, 'hover': $clr-brand-hover, 'header':

    'page-headers/bg-header.jpg' ), 'activity': ( 'color': $clr-kids-activities, 'hover': $clr-kids-activities-hover, 'header': 'page-headers/bg-header-pink.jpg' ), 'parenting': ( 'color': $clr-parenting, 'hover': $clr-parenting-hover, 'header': 'page-headers/bg-header-orange.jpg' ), ); Future
  127. @onishiweb @each $theme, $settings in $archive-themes { ! $color:map-get($settings, 'color');

    $hover:map-get($settings, 'hover'); $header:map-get($settings, 'header'); ! $class:'.archive'; ! @if( $theme != 'default') { $class: '.archive.#{$theme}'; } ! #{$class} { […] } } Future
  128. @onishiweb Future

  129. @onishiweb ScssLint Future https://github.com/causes/scss-lint

  130. @onishiweb Future

  131. @onishiweb scsslint: { core: ['app/scss/core/**/*.scss'], options: { bundleExec: true, config:

    '.scss-lint.yml', reporterOutput: 'scss-lint-report.xml', colorizeOutput: true, maxBuffer: NaN }, }, Future
  132. @onishiweb Future

  133. @onishiweb uCSS / unCSS Future https://github.com/ullmark/grunt-ucss https://github.com/giakki/uncss

  134. @onishiweb Shame.css http://csswizardry.com/2013/04/shame-css/ Future

  135. @onishiweb core/ |- partials/ | |- pages/ | |- components/

    | |- themes/ | |- shame/ | | |- _kids-activities.scss | | |- _products.scss | | |- _solve-your-stain.scss Future
  136. @onishiweb Autoprefixer vs. Compass mixins Future

  137. @onishiweb Performance Future

  138. @onishiweb Multiple stylesheets Future http://css-tricks.com/one-two-three/

  139. @onishiweb Critical path (head.css) Future

  140. @onishiweb We’re all still learning

  141. @onishiweb Thank You!