Slide 1

Slide 1 text

Refactoring CSS @johnwlong CSS Dev Conf 2014 #refactorcss Programming Principles for Designers

Slide 2

Slide 2 text

#refactorcss

Slide 3

Slide 3 text

www.thesassway.com #refactorcss

Slide 4

Slide 4 text

www.uservoice.com #refactorcss

Slide 5

Slide 5 text

Why refactor your CSS? #refactorcss

Slide 6

Slide 6 text

#refactorcss In the beginning…

Slide 7

Slide 7 text

#refactorcss Designers writing CSS

Slide 8

Slide 8 text

#refactorcss vs. Design FIGHT!!!! Programming

Slide 9

Slide 9 text

“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

Slide 10

Slide 10 text

#refactorcss

Slide 11

Slide 11 text

CSS === Programming #refactorcss

Slide 12

Slide 12 text

You are a programmer #refactorcss

Slide 13

Slide 13 text

We have a lot to learn from programmers #refactorcss The CSS Community

Slide 14

Slide 14 text

What is refactoring? #refactorcss

Slide 15

Slide 15 text

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.

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

#refactorcss SMACSS smacss.com BEM bem.info OOCSS oocss.org This is Modular CSS! www.thesassway.com/modular-css

Slide 18

Slide 18 text

What is MODULAR CSS? #refactorcss

Slide 19

Slide 19 text

Modular CSS Objects .button Child Objects .button-icon Subclasses .primary-button Modifiers .is-selected www.thesassway.com/modular-css #refactorcss

Slide 20

Slide 20 text

An Example #refactorcss

Slide 21

Slide 21 text

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; bit.ly/menu-1 1 #refactorcss

Slide 22

Slide 22 text

.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

Slide 23

Slide 23 text

.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

Slide 24

Slide 24 text

www.thesassway.com/modular-css #refactorcss

Slide 25

Slide 25 text

Learn to think in objects. Not selectors. #refactorcss

Slide 26

Slide 26 text

Refactoring Patterns #refactorcss

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

• Extracting Objects • Extracting Child-Objects • Extracting Subclasses • Extracting Modifiers #refactorcss 1. Abstraction

Slide 29

Slide 29 text

• Decomposing objects • Assembling larger components from several objects • Extracting Mixins and Functions • Removing duplication (DRY) #refactorcss 2. Breaking up code

Slide 30

Slide 30 text

• 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

Slide 31

Slide 31 text

More Examples #refactorcss

Slide 32

Slide 32 text

#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

Slide 33

Slide 33 text

#refactorcss Renaming a selector Save changes

Slide 34

Slide 34 text

.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

Slide 35

Slide 35 text

! Cancel ! Save changes #refactorcss Extracting a subclass #refactorcss

Slide 36

Slide 36 text

.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

Slide 37

Slide 37 text

!
Hiya!
Success!
Whoops!
#refactorcss Extracting a superclass #refactorcss

Slide 38

Slide 38 text

.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; }

Slide 39

Slide 39 text

!
Hiya!
Success!
Whoops!
#refactorcss #refactorcss Extracting a placeholder superclass

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

! Next #refactorcss Decomposing objects #refactorcss

Slide 42

Slide 42 text

.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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Pros and cons
 exist for each type of refactoring #refactorcss (This list was not exhaustive.)

Slide 46

Slide 46 text

Best Practices #refactorcss

Slide 47

Slide 47 text

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.

Slide 48

Slide 48 text

1. Don’t try to refactor AND add functionality at the same time. #refactorcss Taken from the book, “The Pragmatic Programmer”

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

TESTING CSS #refactorcss

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

bit.ly/css-for-grownups #refactorcss

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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