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

Refactoring CSS - Programming Principles for Designers

A204ca511ddee820957e715d6d363548?s=47 John W. Long
October 14, 2014

Refactoring CSS - Programming Principles for Designers

From my presentation at CSS Dev Conf 2014.

Abstract:

Over the years as designers have transitioned from print to the web we've had a reluctant relationship with code. Pixel perfection is a demanding standard. It's required us to get close to the metal and learn HTML and CSS. Some of us have transitioned well and have actually grown to love our curly-braces and semicolons, but it wasn't what we trained for.

For programmers on the other hand, writing code and doing it well is the primary part of their job. And there's actually a lot that we can learn from them about writing good CSS.

In this talk, John will examine a number of programming principles and demonstrate how they apply within the context of CSS. Principles like:

* Keeping your code DRY (Don't repeat yourself)
* Abstracting common problems
* Choosing great names
* Creating a well structured project
* Being aware of common code smells
* Making your code more modular

You are certain to walk away with something to apply to your current project.

See also:
* http://bit.ly/css-for-grownups
* http://bit.ly/defensive-sass-sept-2013
* http://thesassway.com/modular-css

A204ca511ddee820957e715d6d363548?s=128

John W. Long

October 14, 2014
Tweet

Transcript

  1. Refactoring CSS @johnwlong CSS Dev Conf 2014 #refactorcss Programming Principles

    for Designers
  2. #refactorcss

  3. www.thesassway.com #refactorcss

  4. www.uservoice.com #refactorcss

  5. Why refactor your CSS? #refactorcss

  6. #refactorcss In the beginning…

  7. #refactorcss Designers writing CSS

  8. #refactorcss vs. Design FIGHT!!!! Programming

  9. “It’s almost a challenge to find a development team that’s

    working on a codebase that’s more than a couple of years old where the CSS isn’t the most frightening and hated part of that system.” #refactorcss Andy Hume CSS for Grownups SXSW Interactive, 2012 bit.ly/css-for-grownups
  10. #refactorcss

  11. CSS === Programming #refactorcss

  12. You are a programmer #refactorcss

  13. We have a lot to learn from programmers #refactorcss The

    CSS Community
  14. What is refactoring? #refactorcss

  15. Refactoring A disciplined approach to changing code to make it

    easy to understand and cheaper to modify in the future
 without changing its observed behavior. #refactorcss Based on Martin Fowler’s definition.
  16. Goals of Refactoring • Clean maintainable code • Easy to

    understand • Composable parts • Reusable without modification • Parts behave the same in all contexts • Hard to break #refactorcss
  17. #refactorcss SMACSS smacss.com BEM bem.info OOCSS oocss.org This is Modular

    CSS! www.thesassway.com/modular-css
  18. What is MODULAR CSS? #refactorcss

  19. Modular CSS Objects .button Child Objects .button-icon Subclasses .primary-button Modifiers

    .is-selected www.thesassway.com/modular-css #refactorcss
  20. An Example #refactorcss

  21. ul.menubar { background: white; @include box-shadow(rgba(black, 0.2) 0 1 list-style:

    none; font-size: 14px; padding: 0 10px; > li { display: inline-block; position: relative; > a { color: black; display: block; padding: 10px 14px; text-decoration: none; &:hover { background: #29a7f5; color: white; } } > ul { @include box-shadow(rgba(black, 0.5) 0 @include border-radius(3px); @include border-top-left-radius(0); display: none; position: absolute; <ul class="menubar"> <li> <a href="#">File</a> <ul> <li><a href="#">Open</a></li> <li><a href="#">Save</a></li> <li><a href="#">Save as...</a></li> <li><a href="#">Close</a></li> <li class="separator"></li> <li><a href="#">Exit</a></li> </ul> </li> ... </ul> bit.ly/menu-1 1 #refactorcss
  22. <ul class="menubar"> <li> <a class="menubar-item" href="#">File</a> <ul class="menu" > <li><a

    class="menu-item" href="#">Open</a></li> <li><a class="menu-item" href="#">Save</a></li> <li><a class="menu-item" href="#">Save as...</a></li> <li><a class="menu-item" href="#">Close</a></li> <li class="menu-separator"></li> <li><a class="menu-item" href="#">Exit</a></li> </ul> </li> ... </ul> .menubar { background: white; @include box-shadow(rgba(black, 0.2) 0 1 list-style: none; font-size: 14px; padding: 0 10px; > li { display: inline-block; position: relative; } } .menubar-item { color: black; display: block; padding: 10px 14px; text-decoration: none; &:hover { background: #29a7f5; color: white; } } .menu { @include box-shadow(rgba(black, 0.5) 0 5 @include border-radius(3px); @include border-top-left-radius(0); 2 bit.ly/menu-2 #refactorcss
  23. <ul class="menubar"> <li class="menubar-item" > <a class="menubar-item-target" href="#">File</a> <ul class="menu"

    > <li class="menu-item" ><a class="menu-item-target" href="#">Open</a></li> <li class="menu-item" ><a class="menu-item-target" href="#">Save</a></li> <li class="menu-item" ><a class="menu-item-target" href="#">Save as...</a></li> <li class="menu-item" ><a class="menu-item-target" href="#">Close</a></li> <li class="menu-separator"></li> <li class="menu-item" ><a class= "menu-item-target" href="#">Exit</a></li> </ul> </li> ... </ul> .menubar { background: white; @include box-shadow(rgba(black, 0.2) 0 1 list-style: none; font-size: 14px; padding: 0 10px; } .menubar-item { display: inline-block; position: relative; } .menubar-item-target { color: black; display: block; padding: 10px 14px; text-decoration: none; &:hover { background: #29a7f5; color: white; } } 3 bit.ly/menu-3 #refactorcss
  24. www.thesassway.com/modular-css #refactorcss

  25. Learn to think in objects. Not selectors. #refactorcss

  26. Refactoring Patterns #refactorcss

  27. 1.Techniques for abstraction 2.Techniques for breaking up code 3.Techniques for

    improving names #refactorcss http://en.wikipedia.org/wiki/Code_refactoring Refactoring Categories
  28. • Extracting Objects • Extracting Child-Objects • Extracting Subclasses •

    Extracting Modifiers #refactorcss 1. Abstraction
  29. • Decomposing objects • Assembling larger components from several objects

    • Extracting Mixins and Functions • Removing duplication (DRY) #refactorcss 2. Breaking up code
  30. • Simplify a selector (Remove ID or Element selectors) •

    Renaming objects, mixins, functions, variables • Move into superclass • Move into subclass • Refactor comment to mixin #refactorcss 3. Improving names
  31. More Examples #refactorcss

  32. #content form button, #sidebar button { border: none; border-radius: 5px;

    background: $green; box-shadow: $dark-green -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; } #refactorcss .button { border: none; border-radius: 5px; background: $green; box-shadow: $dark-green -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; } Renaming a selector
  33. #refactorcss Renaming a selector <button class="button">Save changes</button>

  34. .button { border: none; border-radius: 5px; background: $green; box-shadow: $dark-green

    -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; } #refactorcss .button { border: none; border-radius: 5px; background: $gray; box-shadow: $dark-gray -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; } ! .primary-button { background: $green; box-shadow: $dark-green 0 -4px 0 0 inset } ! Extracting a subclass
  35. ! <button class="button">Cancel</button> ! <button class="button primary-button">Save changes</button> #refactorcss Extracting

    a subclass #refactorcss
  36. .info { color: $white; background: $blue; padding: 20px; } .success

    { color: $white; background: $green; padding: 20px; } .failure { color: $white; background: $red; padding: 20px; } #refactorcss .message { color: $white; padding: 20px; } .info-message { background: $blue; } .success-message { background: $green; } .failure-message { background: $red; } Extracting a superclass
  37. ! <div class="message info-message">Hiya!</div> <div class="message success-message">Success!</div> <div class="message failure-message">Whoops!</div>

    #refactorcss Extracting a superclass #refactorcss
  38. .info { color: $white; background: $blue; padding: 20px; } .success

    { color: $white; background: $green; padding: 20px; } .failure { color: $white; background: $red; padding: 20px; } #refactorcss %message { color: $white; padding: 20px; } .info { @extend %message; background: $blue; } .success { @extend %message; background: $green; } .failure { @extend %message; background: $red; } Extracting a placeholder superclass .info, .success, .failure { color: $white; padding: 20px; } .info { background: $blue; } .success { background: $green; } .failure { background: $red; }
  39. ! <div class="info">Hiya!</div> <div class="success">Success!</div> <div class="failure">Whoops!</div> #refactorcss #refactorcss Extracting

    a placeholder superclass
  40. button.next { border: none; border-radius: 5px; background: $gray; box-shadow: $dark-gray

    -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; ! &:after { @include icon(next); } } #refactorcss .button { border: none; border-radius: 5px; background: $gray; box-shadow: $dark-gray -4px 0 0 inset; color: white; font: 100 18px/1.5 sans-serif; padding: 8px 25px 11px; } .right-arrow-icon { @include icon(next); } Decomposing objects
  41. ! <button class="button"> <i class="right-arrow-icon"></i> Next </button> #refactorcss Decomposing objects

    #refactorcss
  42. .video { padding: 10px; border: $border-color; margin: 10px 0; min-width:

    400px; ! // Crazy IE5-6 min-width hack * html & { width: expression( document.body.clientWidth < 400 ? 400px : "auto" ) ; } #refactorcss @mixin crazy-ie-min-width-hack($width) { * html & { width: unquote( 'expression(' + 'document.body.clientWidth < ' + ($width + 1) + ' ? ' + $width + 'px : "auto")' ); } } ! .video { min-width: 400px; @include crazy-ie-min-width-hack(400); } Refactor to comment
  43. .button { border: none; background: black; color: white; padding: 15px

    8px; } #refactorcss .legacy .button { border: none; background: black; color: white; padding: 15px 8px; } Namespacing styles
  44. .button { border: none; background: black; color: white; padding: 15px

    8px; } #refactorcss .legacy-button { border: none; background: black; color: white; padding: 15px 8px; } Prefixing styles
  45. Pros and cons
 exist for each type of refactoring #refactorcss

    (This list was not exhaustive.)
  46. Best Practices #refactorcss

  47. A disciplined approach to changing code to make it easy

    to understand and cheaper to modify in the future
 without changing its observed behavior. #refactorcss Refactoring Based on Martin Fowler’s definition.
  48. 1. Don’t try to refactor AND add functionality at the

    same time. #refactorcss Taken from the book, “The Pragmatic Programmer”
  49. 2. Make sure you have good tests BEFORE refactoring #refactorcss

    Taken from the book, “The Pragmatic Programmer”
  50. 3. Take short deliberate steps AND test after each step

    #refactorcss Taken from the book, “The Pragmatic Programmer”
  51. 4. Refactor early and often #refactorcss Taken from the book,

    “The Pragmatic Programmer”
  52. TESTING CSS #refactorcss

  53. 1. Manual testing • Paging through your site by hand

    • Example pages or Styleguides 2. Automated Testing • Regression testing (Phantom CSS, Wraith, CSSert) • Linting (CSS Lint, SCSS Lint) • Coverage (CSS Coverage for Firefox) #refactorcss Tools for testing CSS Visit www.csste.st for more test tools
  54. bit.ly/css-for-grownups #refactorcss

  55. bit.ly/defensive-sass-sept-2013 #refactorcss

  56. Questions? #refactorcss Books • “Refactoring: Ruby Edition” — Martin Fowler

    • “The Pragmatic Programmer” — Dave Thomas & Andy Hunt
 More on Modular CSS • thesassway.com/modular-css
 Twitter • @thesassway • @johnwlong